Dzieje się tak, gdy znacząco zmienia się jeden z obiektów, które łączysz z plikiem wykonywalnym. Na przykład zyskuje lub traci kilka linii kodu, który można profilować.
Minimalna wielkość błędu to 2 pliki źródłowe. Oto przykład 2 pliki źródłowe zwane main.c ...
/* main.c */
int do_stuff(int value);
int main(int argc, const char *argv[])
{
do_stuff(argc);
return 0;
}
i 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;
}
Co robią nie jest ważne. Aby je zbudować, tutaj jest prosta Makefile:
CFLAGS := -fprofile-arcs -ftest-coverage
LDFLAGS := -fprofile-arcs -ftest-coverage
testexe: main.o stuff.o
$(CC) $(LDFLAGS) -o [email protected] $^
Makefile jest skonfigurowany tak, że kompilacja jest main.c -> main.o
, stuff.c -> stuff.o
i wreszcie stuff.o + main.o -> testexe
. Jeśli skompilujemy i połączemy te pliki C z opcjami -fprofile-arcs -ftest-coverage
, to plik wykonywalny ma profilowanie. Uruchom to execuatable, a otrzymasz 2 pliki wyjściowe, main.gcda
i stuff.gcda
. Jak na razie dobrze.
Teraz zmień linię #if 0
na #if 1
. Plik Makefile powinien spowodować, że just stuff.c będzie rekompilował, a plik wykonywalny będzie się ponownie łączyć. Następnym razem, gdy uruchomisz plik wykonywalny testu, pojawi się komunikat "Niezgodność scalania" dla pliku main.gcda. Nie ma to wpływu na plik stuff.gcda, ponieważ jego plik obiektowy został odtworzony z wszystkimi nowymi informacjami podsumowującymi. Jeśli ponownie skompilujesz plik main.c
i ponownie złączysz plik wykonywalny, komunikat błędu zniknie.
Co można zrobić? Chciałbym wiedzieć! W tej chwili uruchamiam find . -name '*.gcda' | xargs rm
ilekroć potrzebuję ponownie sprawdzić zasięg, który nie jest idealny. Innym rozwiązaniem byłoby przekompilowanie wszystkiego podczas korzystania z profilowania "na wszelki wypadek", ale to wydaje się przesadą.
Świetne, dzięki za informacje! Miło jest w końcu zrozumieć, co tu się dzieje. Doskonałe wyjaśnienie też. Miałem podobne obejście - aby usunąć wszystkie wygenerowane pliki przed uruchomieniem. Rozumiem teraz, dlaczego to działa, ale myślę, że komunikat o błędzie mógł zostać nieco poprawiony. – mikelong