【发布时间】:2014-11-06 04:31:14
【问题描述】:
我正在使用 gcc 和 gcov 中的覆盖率支持来分析一个大型项目的覆盖率。我还在运行随机测试以尝试增加覆盖率。理想情况下,当我生成一个测试时,如果它增加了任何覆盖率指标,我想保存它。
什么是解决这个问题的可靠方法?
例如,假设我们有类似的东西
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[]) {
int x, y;
x = atoi(argv[1]);
y = atoi(argv[2]);
if (x < 0 || y < 0) {
x = -x;
y = -y;
}
}
我用
编译gcc -fprofile-arcs -ftest-coverage -o test test.c
有没有办法检测覆盖率是否增加,并保存相应的输入? 例如使用类似
while [ 1 ];
do
./gen_test.sh > input.txt
./test < input.txt
if [ COVERAGE_INCREASED ] then save input.txt fi
done;
运行 gcov 以生成报告需要花费大量时间,因此我希望在程序退出后立即知道覆盖范围是否增加。
我知道我可以查看 .gcda 文件并查看它们是否已更改。不幸的是,这不是一个可靠的解决方案,因为我正在并行运行随机测试,我希望“增加覆盖率”测试是原子的——项目很大,gcda/源文件的数量很大。
我假设如果这样的事情是可能的,我需要在我的 main 中添加一些特定于 gcc 的代码,但我不知道去哪里找。
尝试 1:我从源代码 (4.6.3) 编译了 gcc,并查看了 gcov 代码。当覆盖测试程序退出时,它会运行一些合并函数来更新文件中已经存在的覆盖数据。我已经更新了其中一个合并函数 (libgcov.c),以便在覆盖范围已积极更新时打印一些内容,这似乎符合我的目的。
/* The profile merging function that just adds the counters. It is given
an array COUNTERS of N_COUNTERS old counters and it reads the same number
of counters from the gcov file. */
void
__gcov_merge_add (gcov_type *counters, unsigned n_counters)
{
gcov_type prev;
for (; n_counters; counters++, n_counters--) {
prev = gcov_read_counter ();
if (prev == 0 && *counters > 0) {
fprintf(stdout, "Coverage increase by add");
}
*counters += prev;
}
}
它似乎在为线路覆盖做正确的事情,但它缺少分支覆盖。此外,它不会捕获初始运行,但这不是一个问题。
运行上面的例子,我得到了
./test 0 0
./test -1 0
Coverage increase by add
./test 0 -1
【问题讨论】:
标签: c++ c gcc code-coverage gcov