这是因为你正在编译common.c
两次不同的时间。
运行 ut1 和 ut2 程序时,我们可以看到以下警告(使用 GCC 10 测试):
$ ./ut1
fun1
$ ./ut2
fun2
libgcov profiling error:/tmp/gcov-test/common.gcda:overwriting an existing profile data with a different timestamp
每次在启用覆盖率的情况下进行编译时,GCC 都会为覆盖率数据分配一个校验和。该校验和主要由 gcov 工具用来确保 gcno 文件和 gcda 文件匹配。编译ut1和ut2时,将使用不同的校验和。所以而不是追加覆盖率数据,ut2 看到无效的校验和并将覆盖数据。
解决办法是治疗common.c
作为一个单独的编译单元并将其与 ut1 和 ut2 链接。例如:
# compile common.c
gcc -Wall --coverage -c common.c -o common.o
# compile ut1 and ut2, and link with common.o
gcc -Wall --coverage ut1.c common.o -o ut1
gcc -Wall --coverage ut2.c common.o -o ut2
然后,gcov 输出应该符合预期:
-: 0:Source:common.c
-: 0:Graph:common.gcno
-: 0:Data:common.gcda
-: 0:Runs:2
-: 1:#include<stdio.h>
1: 2:void fun1(){
1: 3: printf("fun1\n");
1: 4:}
-: 5:
1: 6:void fun2(){
1: 7: printf("fun2\n");
1: 8:}
如果您无法更改项目的编译方式,您可以使用 lcov 或 gcovr 等工具收集覆盖率数据,然后合并它。例如,gcovr 的工作流程如下:
-
编译 ut1,执行它,并将覆盖率数据保存为 gcovr JSON 报告:
gcc -Wall --coverage ut1.c common.c -o ut1
./ut1
gcovr --json ut1.json
rm *.gcda *.gcno
-
编译 ut2,执行它,并将覆盖率数据保存为 gcovr JSON 报告:
gcc -Wall --coverage ut2.c common.c -o ut2
./ut2
gcovr --json ut2.json
-
创建合并报告:
gcovr -a ut1.json -a ut2.json --html-details coverage.html
虽然 gcovr 无法输出 gcov 样式的文本报告,但它可以将覆盖范围显示为 HTML:
Full code for this answer is at https://gist.github.com/latk/102b125dff160484f93d8997204fc201 https://gist.github.com/latk/102b125dff160484f93d8997204fc201