Pergunta

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)
Foi útil?

Solução

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top