Как создать отчеты о покрытии для детей fork()'d с помощью gcov/lcov?


У меня возникли проблемы с созданием отчетов о покрытии для моего проекта-похоже, что линии в дочернем процессе после вилки никогда не попадают, хотя они явно существуют в реальности.

Здесь отчет о комбинезонах части разветвления (результаты те же с lcov+genhtml), и журналы сборки .

Проект использует autotools с libtool для сборки и упаковывает все как статическую библиотеку. (configure.ac, библиотека makefile.am, Тесты makefile.am )

Я попытался добавить флаги покрытия в тесты и --coverage в CFLAGS, но безрезультатно.

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

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>

int main(void)
{
    pid_t pid;
    if (!(pid = fork())) {
        puts("In child");
    } else {
        puts("In parent");
        waitpid(pid, NULL, 0);
    }
    return 0;
}

Со следующей сессией оболочки:

/bin/sh ./libtool  --tag=CC   --mode=compile gcc -DHAVE_CONFIG_H -I. -I./src    -Wall -Wextra -Wno-unused-result -Wno-missing-field-initializers -std=gnu99 -fplan9-extensions -I./include/ -I./dependencies/csptr/include/ -O0 --coverage -fprofile-arcs -ftest-coverage -g -O0 -MT test.lo -MD -MP -MF test.Tpo -c -o test.lo test.c
/bin/sh ./libtool  --tag=CC   --mode=link gcc -Wall -Wextra -Wno-unused-result -Wno-missing-field-initializers -std=gnu99 -fplan9-extensions -I./include/ -I./dependencies/csptr/include/ -O0 --coverage -fprofile-arcs -ftest-coverage -g -O0 -lgcov  -o test -rpath /usr/local/lib test.lo
#The two lines above are adapted versions of what autotools with libtool run to compile my project.

./test
mkdir -p coverage
lcov --compat-libtool --directory . --capture --output-file cov.info && genhtml -o coverage cov.info

... но сгенерированный отчет объявляет о 100% охвате.

Что случилось ? Мое телосложение сломано ?

1 2

1 ответ:

Через некоторое время, когда я повторно исследовал проблему, я смог ее отследить:

Я использовал _exit() для завершения дочернего процесса, и он имеет свойство обходить любое завершение процесса, а вместе с ним и Вызов __gcov_flush() - Вот почему я не получал никакого покрытия.