16 Stimmen

Wie erzwingt man den Abbruch bei "glibc detected *** free(): invalid pointer"?

In Linux-Umgebung, wenn immer "Glibc erkannt *** free(): ungültiger Zeiger" Fehler, wie kann ich identifizieren, welche Zeile des Codes verursacht es?

Gibt es eine Möglichkeit, einen Abbruch zu erzwingen? Ich erinnere mich, dass es eine ENV-Variable gibt, um dies zu steuern?

Wie man einen Haltepunkt in gdb für den Glibc-Fehler zu setzen?

0 Stimmen

Ich denke, diese Frage muss je nach System unterschiedlich beantwortet werden und ist nicht auf Linux beschränkt (z.B. OpenBSD, OSX).

16voto

DGentry Punkte 15830

Ich glaube, wenn Sie setenv MALLOC_CHECK_ auf 2, ruft die Glibc abort() wenn es den Fehler "free(): ungültiger Zeiger" feststellt. Beachten Sie den nachgestellten Unterstrich im Namen der Umgebungsvariablen.

Wenn MALLOC_CHECK_ 1 ist, gibt die Glibc "free(): ungültiger Zeiger" aus (und ähnliche printfs für andere Fehler). Wenn MALLOC_CHECK_ 0 ist, wird die Glibc solche Fehler ignorieren und einfach zurückkehren. Falls MALLOC_CHECK_ 3 ist, druckt die Glibc die Meldung aus und ruft dann abort() . D.h. es ist eine Bitmaske.

Sie können auch anrufen mallopt(M_CHECK_ACTION, arg) mit einem Argument von 0-3 und erhalten das gleiche Ergebnis wie mit MALLOC_CHECK_ .

Da Sie die Meldung "free(): ungültiger Zeiger" sehen, denke ich, dass Sie bereits die folgenden Einstellungen vorgenommen haben müssen MALLOC_CHECK_ oder Aufruf mallopt() . Standardmäßig gibt die Glibc diese Meldungen nicht aus.

Was die Fehlersuche anbelangt, so kann die Installation eines Handlers für SIGABRT ist wahrscheinlich der beste Weg, um fortzufahren. Sie können einen Haltepunkt in Ihrem Handler setzen oder absichtlich einen Core-Dump auslösen.

0 Stimmen

Wo kann ich MALLOC_CHECK einstellen, damit es wirksam wird?

7voto

dicroce Punkte 43066

Ich empfehle Ihnen, valgrind zu kaufen:

valgrind --tool=memcheck --leak-check=full ./a.out

2 Stimmen

Sie werden mehrere Durchläufe haben, also bringen Sie valgrind dazu, einen Dateinamen auszugeben, der auf der aktuellen Zeit basiert. valgrind--tool=memcheck --leak-check=full --log-file= date +%s -vg.txt ./a.out

3voto

Adrian Punkte 1784

Im Allgemeinen sieht es so aus, als ob Sie die glibc neu kompilieren müssten, igitt.

Sie sagen nicht, in welcher Umgebung Sie arbeiten, aber wenn Sie Ihren Code für OS X neu kompilieren können, dann hat dessen Version von libc ein free(), das auf diese Umgebungsvariable hört:

MallocErrorAbort             If set, causes abort(3) to be called if an
                              error was encountered in malloc(3) or
                              free(3) , such as a calling free(3) on a
                              pointer previously freed.

Die Manpage für free() unter OS X enthält weitere Informationen.

Wenn Sie mit Linux arbeiten, versuchen Sie Valgrind kann es einige unmöglich zu jagende Fehler finden.

3voto

mat_geek Punkte 2450

Wie setzt man einen Haltepunkt in gdb?

(gdb) b Dateiname:Leinennummer // z.B. b main.cpp:100

Gibt es eine Möglichkeit, einen Abbruch zu erzwingen? Ich erinnere mich, dass es eine ENV-Variable gibt, um dies zu steuern?

Ich hatte den Eindruck, dass er standardmäßig abbricht. Stellen Sie sicher, dass Sie die Debug-Version installiert haben.

Oder verwenden Sie libdmalloc5: "Drop-in-Ersatz für die systemeigene malloc', realloc', calloc', free' und andere Speicherverwaltungsroutinen und bietet gleichzeitig leistungsstarke Debugging-Möglichkeiten die während der Laufzeit konfiguriert werden können. Zu diesen Möglichkeiten gehören u.a. die Verfolgung von Speicherlecks, die Erkennung von Fence-Post-Write, die Meldung von Datei-/Zeilennummern und die allgemeine Protokollierung von Statistiken."

Fügen Sie Ihrem Link-Befehl Folgendes hinzu

-L/usr/lib/debug/lib -ldmallocth

gdb sollte automatisch die Kontrolle zurückgeben, wenn die Glibc einen Abbruch auslöst.

Oder Sie können einen Signalhandler für SIGABRT einrichten, der den Stacktrace in eine fd (Dateideskriptor) ausgibt. Unten ist mp_logfile eine FILE*

void *array[512 / sizeof(void *)]; // 100 is just an arbitrary number of backtraces, increase if you want.
size_t size;

size = backtrace (array, 512 / sizeof(void *));
backtrace_symbols_fd (array, size, fileno(mp_logfile));

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X