2010-04-07 6 views

Antwort

32

Dies geschieht, wenn sich eines der Objekte, die Sie in eine ausführbare Datei verknüpfen, erheblich ändert. Zum Beispiel gewinnt oder verliert es einige Zeilen von profilierbarem Code.

Der minimale Fall, um den Fehler zu erzeugen, ist mit 2 Quelldateien. Hier sind zwei Beispiel-Quelldateien genannt main.c ...

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

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

und 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; 
} 

Was sie tun, ist nicht wichtig. Um sich zu bauen, hier ist ein einfaches Makefile:

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

testexe: main.o stuff.o 
    $(CC) $(LDFLAGS) -o [email protected] $^ 

Das Makefile ist so eingestellt, dass die Zusammenstellung main.c -> main.o ist, stuff.c -> stuff.o und schließlich stuff.o + main.o -> testexe. Wenn wir diese C-Dateien mit den Optionen -fprofile-arcs -ftest-coverage kompilieren und verknüpfen, verfügt die ausführbare Datei über eine Profilerstellung. Führen Sie das Executable aus, und Sie werden 2 Ausgabedateien main.gcda und stuff.gcda erhalten. So weit, ist es gut.

Jetzt ändern Sie die Zeile #if 0 zu #if 1. Das Makefile sollte dazu führen, dass nur stuff.c neu kompiliert wird und die ausführbare Datei neu verknüpft wird. Wenn Sie das nächste Mal die ausführbare Testdatei ausführen, erhalten Sie die Meldung "Merge Mismatch" für die Datei main.gcda. Die Datei stop.gcda ist nicht betroffen, da ihre Objektdatei mit allen neuen Zusammenfassungsinformationen neu erstellt wurde. Wenn Sie main.c neu kompilieren und die ausführbare Datei erneut verknüpfen, wird die Fehlermeldung nicht mehr angezeigt.

Was kann also getan werden? Ich würde es gerne wissen! Im Moment laufe ich find . -name '*.gcda' | xargs rm immer wenn ich die Abdeckung neu überprüfen muss, was nicht wirklich ideal ist. Eine andere Lösung wäre es, alles neu zu kompilieren, wenn man "nur für den Fall" ein Profiling verwendet, aber das erscheint als Overkill.

+1

Großartig, danke für die Information! Es ist schön, endlich zu verstehen, was hier vor sich geht. Hervorragende Erklärung auch. Ich hatte eine ähnliche Problemumgehung - um alle erzeugten Dateien vor der Ausführung zu löschen. Ich verstehe jetzt, warum das funktioniert, aber ich denke, die Fehlermeldung könnte etwas verbessert werden. – mikelong