如何使用 gcov/lcov 为 fork() 的 children 生成覆盖率报告?
How do I generate coverage reports for fork()'d children using gcov/lcov?
我在为我的一个项目生成覆盖率报告时遇到了问题 -- child 进程中的行似乎从未被命中,尽管它们显然是真实的。
这里是 coveralls report of the forking part (The results are the same with lcov+genhtml), and the build logs.
该项目使用 autotools 和 libtool 构建,并将所有内容打包为静态库。 (configure.ac, library makefile.am, tests makefile.am)
我尝试将覆盖率标志添加到测试中,并在 CFLAGS 中添加 --coverage
,但无济于事。
最让我烦恼的是我试图在一个简单的 C 文件上重现该行为,如下所示:
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
int main(void)
{
pid_t pid;
if (!(pid = fork())) {
puts("In child");
} else {
puts("In parent");
waitpid(pid, NULL, 0);
}
return 0;
}
以下 shell 会话:
/bin/sh ./libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I./src -Wall -Wextra -Wno-unused-result -Wno-missing-field-initializers -std=gnu99 -fplan9-extensions -I./include/ -I./dependencies/csptr/include/ -O0 --coverage -fprofile-arcs -ftest-coverage -g -O0 -MT test.lo -MD -MP -MF test.Tpo -c -o test.lo test.c
/bin/sh ./libtool --tag=CC --mode=link gcc -Wall -Wextra -Wno-unused-result -Wno-missing-field-initializers -std=gnu99 -fplan9-extensions -I./include/ -I./dependencies/csptr/include/ -O0 --coverage -fprofile-arcs -ftest-coverage -g -O0 -lgcov -o test -rpath /usr/local/lib test.lo
#The two lines above are adapted versions of what autotools with libtool run to compile my project.
./test
mkdir -p coverage
lcov --compat-libtool --directory . --capture --output-file cov.info && genhtml -o coverage cov.info
...但生成的报告宣布覆盖率为 100%。
怎么了?我的构建坏了吗?
一段时间后,当我重新调查这个问题时,我能够找到它:
我正在使用 _exit()
终止子进程,它具有 属性 绕过进程的任何终结,以及对 __gcov_flush()
的调用——这个这就是为什么我没有得到任何报道。
我在为我的一个项目生成覆盖率报告时遇到了问题 -- child 进程中的行似乎从未被命中,尽管它们显然是真实的。
这里是 coveralls report of the forking part (The results are the same with lcov+genhtml), and the build logs.
该项目使用 autotools 和 libtool 构建,并将所有内容打包为静态库。 (configure.ac, library makefile.am, tests makefile.am)
我尝试将覆盖率标志添加到测试中,并在 CFLAGS 中添加 --coverage
,但无济于事。
最让我烦恼的是我试图在一个简单的 C 文件上重现该行为,如下所示:
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
int main(void)
{
pid_t pid;
if (!(pid = fork())) {
puts("In child");
} else {
puts("In parent");
waitpid(pid, NULL, 0);
}
return 0;
}
以下 shell 会话:
/bin/sh ./libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I./src -Wall -Wextra -Wno-unused-result -Wno-missing-field-initializers -std=gnu99 -fplan9-extensions -I./include/ -I./dependencies/csptr/include/ -O0 --coverage -fprofile-arcs -ftest-coverage -g -O0 -MT test.lo -MD -MP -MF test.Tpo -c -o test.lo test.c
/bin/sh ./libtool --tag=CC --mode=link gcc -Wall -Wextra -Wno-unused-result -Wno-missing-field-initializers -std=gnu99 -fplan9-extensions -I./include/ -I./dependencies/csptr/include/ -O0 --coverage -fprofile-arcs -ftest-coverage -g -O0 -lgcov -o test -rpath /usr/local/lib test.lo
#The two lines above are adapted versions of what autotools with libtool run to compile my project.
./test
mkdir -p coverage
lcov --compat-libtool --directory . --capture --output-file cov.info && genhtml -o coverage cov.info
...但生成的报告宣布覆盖率为 100%。
怎么了?我的构建坏了吗?
一段时间后,当我重新调查这个问题时,我能够找到它:
我正在使用 _exit()
终止子进程,它具有 属性 绕过进程的任何终结,以及对 __gcov_flush()
的调用——这个这就是为什么我没有得到任何报道。