测量 python 进程中调用的 C 库的覆盖率

发布于 2024-11-04 05:08:18 字数 1660 浏览 3 评论 0原文

让我从示例开始 - 从 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 文件也会生成。问题是它只包含在 python 分叉之前调用的 bar 函数的覆盖率数字。如果 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 to C使用SIP(版本4.7.4)

Let me start with the example - calling library code from python.

This is the library code (compiled into library libfoolib):

#include <stdio.h>

void bar()
{
    printf("bar\n");
}

void foo()
{
    printf("foo\n");
}

And this is the python code calling it:

#!/usr/bin/python25
import sys
import libfoolib
import processing

def callFoo():
    libfoolib.foo()

libfoolib.bar()

process = processing.Process(target=callFoo)
process.start()

When the library is compiled with -ftest-coverage and -fprofile-arcs the compiler properly generates gcno file and when the python code is executed the gcda file also gets generated. The issue is that it only contains coverage numbers for the bar function which gets called before the python's forking. if the foo was also called outside of the python's processing call then all is good.

This is what I get when I run gcov tool on the produced coverage data:

        -:    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:

The question that I have is "Where is my foo coverage data?"

some more details about the environment:

  • CentOS 5.4
  • gcc: 4.1.2 20080704 (Red Hat 4.1.2-46)
  • CMake build (version 2.8.0)
  • python 2.5
  • python to C uses SIP (version 4.7.4)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

想念有你 2024-11-11 05:08:18

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

为了解决这个问题,我在进程结束之前手动调用 __gcov_flush 。由于这是一个静态库,因此需要一个小型 C 存根来完成该工作。

The issue is that the processing library of python is exiting using os._exit. This is a problem since exiting in this way does not call the regular cleanup handlers of the process. It turns out that the instrumentation collects coverage data in buffers it and writes it only on process exit and it does that in the regular process cleanup handlers. Because of those interactions the child process never has the opportunity to write its data and the invocation of foo never gets written.

To fix this I am calling __gcov_flush manually before the end of my process. And since this is a static library there is a need for a small C stub just for that job.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文