Предупреждение gcov: несоответствие слияния для сводок - PullRequest
21 голосов
/ 07 апреля 2010

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

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

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

1 Ответ

35 голосов
/ 21 апреля 2010

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

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

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

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

и stuff.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 и повторной компиляции исполняемого файла.В следующий раз, когда вы запустите тестовый исполняемый файл, вы получите сообщение «Merge mismatch» для файла main.gcda .Файл stuff.gcda не затронут, поскольку его объектный файл был воссоздан со всей новой сводной информацией.Если вы перекомпилируете main.c и перезапустите исполняемый файл, то сообщение об ошибке исчезнет.

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

...