Предупреждение gcov: несоответствие слияния для сводок

Может ли кто-нибудь сказать мне, что означает сообщение gcov «Несоответствие слияния для сводок»? Я нашел сообщение в источнике gcc здесь:

http://www.opensource.apple.com/source/gcc/gcc-5646/gcc/libgcov.c

Похоже, это проверка работоспособности, тэги в .gcda файлах совпадают, но я не уверен. Кто-нибудь знает, как обойти это?


person mikelong    schedule 07.04.2010    source источник


Ответы (1)


Это происходит, когда один из объектов, которые вы связываете с исполняемым файлом, значительно изменяется. Например, он получает или теряет несколько строк профилируемого кода.

Минимальный случай возникновения ошибки - это 2 исходных файла. Вот 2 примера исходных файлов с именами main.c...

/* main.c */
int do_stuff(int value);

int main(int argc, const char *argv[])
{
    do_stuff(argc);
    return 0;
}

и прочее.c

/* stuff.c */
#include <stdio.h>

#if 0
int more_stuff()
{
    int i;
    i = 0;
    return i;
}
#endif

int do_stuff(int value)
{
    if (value > 1) {
        printf("Value > 1\n");
    } else {
        printf("Value <= 1\n");
    }
    return 0;
}

Что они делают, не важно. Чтобы собрать их, вот простой Makefile:

CFLAGS := -fprofile-arcs -ftest-coverage
LDFLAGS := -fprofile-arcs -ftest-coverage

testexe: main.o stuff.o
    $(CC) $(LDFLAGS) -o $@ $^

Makefile настроен так, что компиляция main.c -> main.o, stuff.c -> stuff.o и, наконец, stuff.o + main.o -> testexe. Если мы скомпилируем и свяжем эти C-файлы с параметрами -fprofile-arcs -ftest-coverage, тогда исполняемый файл будет профилирован. Запустите этот исполняемый файл, и вы получите 2 выходных файла, main.gcda и stuff.gcda. Все идет нормально.

Теперь измените строку #if 0 на #if 1. Makefile должен вызвать перекомпиляцию только stuff.c и повторную компоновку исполняемого файла. В следующий раз, когда вы запустите тестовый исполняемый файл, вы получите сообщение «Несоответствие слияния» для файла main.gcda. Файл stuff.gcda не затрагивается, так как его объектный файл был воссоздан со всей новой сводной информацией. Если вы перекомпилируете main.c и перекомпонуете исполняемый файл, сообщение об ошибке исчезнет.

Так что же можно сделать? Я хотел бы знать! В настоящее время я запускаю find . -name '*.gcda' | xargs rm всякий раз, когда мне нужно перепроверить покрытие, что на самом деле не идеально. Другим решением было бы перекомпилировать все при использовании профилирования «на всякий случай», но это кажется излишним.

person richq    schedule 20.04.2010
comment
Отлично, спасибо за информацию! Приятно наконец понять, что здесь происходит. Тоже отличное объяснение. У меня был похожий обходной путь - удалить все сгенерированные файлы перед запуском. Теперь я понимаю, почему это работает, но я думаю, что сообщение об ошибке можно было бы несколько улучшить. - person mikelong; 25.04.2010