Позвольте мне начать с примера - вызвать библиотечный код из 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
?"
несколько дополнительных сведений об окружающей среде:
Проблема заключается в том, что библиотека обработки python выходит с помощью os._exit
. Это проблема, так как выход таким образом не вызывает регулярных обработчиков очистки процесса. Оказывается, прибор собирает данные о покрытии в буферах и записывает их только на выходе процесса, и это делает это в обработчиках очистки обычного процесса. Из-за этих взаимодействий дочерний процесс никогда не имеет возможности записывать свои данные, а вызов foo
никогда не записывается.
Чтобы исправить это, я вызываю __gcov_flush
вручную до конца моего процесса. И поскольку это статическая библиотека, требуется небольшая заглушка C только для этой работы.