让我从示例开始 - 从python调用库代码。
这是库代码(编译成库libfoolib
):
#include <stdio.h>
void bar()
{
printf("bar\n");
}
void foo()
{
printf("foo\n");
}
这是调用它的python代码:
#!/usr/bin/python25
import sys
import libfoolib
import processing
def callFoo():
libfoolib.foo()
libfoolib.bar()
process = processing.Process(target=callFoo)
process.start()
当使用-ftest-coverage
和-fprofile-arcs
编译库时,编译器会正确生成gcno
文件,并且在执行python代码时,也会生成gcda
文件。问题是它只包含bar
函数的覆盖号,该函数在python的分叉之前被调用。如果foo
也在python的处理调用之外被调用,那么一切都很好。
这是我在生成的覆盖数据上运行gcov
工具时得到的结果:
-: 0:Source:/codeCoverageTests/pythonSIP/foo.c
-: 0:Graph:debug/CMakeFiles/fooLib.dir/foo.c.gcno
-: 0:Data:debug/CMakeFiles/fooLib.dir/foo.c.gcda
-: 0:Runs:4
-: 0:Programs:1
-: 1:#include <stdio.h>
-: 2:
-: 3:void bar()
function bar called 4 returned 100% blocks executed 100%
4: 4:{
4: 5: printf("bar\n");
call 0 returned 100%
4: 6:}
-: 7:
-: 8:void foo()
function foo called 0 returned 0% blocks executed 0%
#####: 9:{
#####: 10: printf("foo\n");
call 0 never executed
#####: 11:}
-: 12:
我的问题是“foo
覆盖率数据在哪里?”
有关环境的更多细节:
答案 0 :(得分:0)
问题是python的处理库正在使用os._exit
退出。这是一个问题,因为以这种方式退出不会调用该进程的常规清理处理程序。事实证明,检测在缓冲区中收集覆盖数据并仅在进程退出时写入它,并且它在常规进程清理处理程序中执行此操作。由于这些交互,子进程永远不会有机会编写其数据,并且foo
的调用永远不会被写入。
要解决此问题,我会在流程结束前手动调用__gcov_flush
。由于这是一个静态库,因此只需要一个小的C存根。