Это происходит, когда один из объектов, которые вы связываете в исполняемый файл, значительно изменяется.Например, он получает или теряет несколько строк профилируемого кода.
Минимальный случай для выдачи ошибки - 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
всякий раз, когда мне нужно перепроверить покрытие, что на самом деле не идеально.Другим решением было бы перекомпилировать все при использовании профилирования «на всякий случай», но это выглядит как перебор.