Измерение покрытия библиотеки C, вызываемой в процессе Python

1

Позвольте мне начать с примера - вызвать библиотечный код из 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 (версия 2.8.0)
  • python 2.5
  • python для C использует SIP (версия 4.7.4)
Теги:
profiling
gcov

1 ответ

0
Лучший ответ

Проблема заключается в том, что библиотека обработки python выходит с помощью os._exit. Это проблема, так как выход таким образом не вызывает регулярных обработчиков очистки процесса. Оказывается, прибор собирает данные о покрытии в буферах и записывает их только на выходе процесса, и это делает это в обработчиках очистки обычного процесса. Из-за этих взаимодействий дочерний процесс никогда не имеет возможности записывать свои данные, а вызов foo никогда не записывается.

Чтобы исправить это, я вызываю __gcov_flush вручную до конца моего процесса. И поскольку это статическая библиотека, требуется небольшая заглушка C только для этой работы.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню