测量在python进程中调用的C库的覆盖范围

时间:2011-05-01 08:39:10

标签: python c linux profiling gcov

让我从示例开始 - 从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覆盖率数据在哪里?”

有关环境的更多细节:

  • CentOS 5.4
  • gcc:4.1.2 20080704(Red Hat 4.1.2-46)
  • CMake build(版本2.8.0)
  • python 2.5
  • python到C使用SIP(版本4.7.4)

1 个答案:

答案 0 :(得分:0)

问题是python的处理库正在使用os._exit退出。这是一个问题,因为以这种方式退出不会调用该进程的常规清理处理程序。事实证明,检测在缓冲区中收集覆盖数据并仅在进程退出时写入它,并且它在常规进程清理处理程序中执行此操作。由于这些交互,子进程永远不会有机会编写其数据,并且foo的调用永远不会被写入。

要解决此问题,我会在流程结束前手动调用__gcov_flush。由于这是一个静态库,因此只需要一个小的C存根。