Domanda

Vorrei iniziare con l'esempio: chiamare il codice della libreria da Python.

Questo è il codice della libreria (compilato in libreria libfoolib):

#include <stdio.h>

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

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

E questo è il codice Python che lo chiama:

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

def callFoo():
    libfoolib.foo()

libfoolib.bar()

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

Quando la libreria viene compilata con -ftest-coverage e -fprofile-arcs il compilatore genera correttamente gcno file e quando il codice Python viene eseguito il gcda Anche il file viene generato. Il problema è che contiene solo numeri di copertura per bar funzione che viene chiamata prima del biforcimento del pitone. se la foo È stato anche chiamato al di fuori della chiamata di elaborazione di Python, quindi tutto è buono.

Questo è quello che ottengo quando corro gcov Strumento sui dati di copertura prodotti:

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

La domanda che ho è "dov'è il mio foo Dati di copertura? "

Alcuni ulteriori dettagli sull'ambiente:

  • CentOS 5.4
  • GCC: 4.1.2 20080704 (Red Hat 4.1.2-46)
  • Cmake Build (versione 2.8.0)
  • Python 2.5
  • Python to C utilizza SIP (versione 4.7.4)
È stato utile?

Soluzione

Il problema è che la libreria di elaborazione di Python sta uscendo usando os._exit. Questo è un problema poiché uscire in questo modo non chiama i normali gestori di pulizia del processo. Si scopre che la strumentazione raccoglie i dati di copertura nei buffer e lo scrive solo all'uscita del processo e lo fa nei gestori di pulizia del processo regolari. A causa di tali interazioni il processo del bambino non ha mai l'opportunità di scrivere i propri dati e l'invocazione di foo Non viene mai scritto.

Per risolvere questo obiettivo, sto chiamando __gcov_flush manualmente prima della fine del mio processo. E poiché questa è una libreria statica, c'è bisogno di un piccolo tb solo per quel lavoro.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top