Ich habe eine Anforderung von Dump Stack-Traces, wenn meine C ++ - Linux-Anwendung abstürzt. Ich konnte dies erfolgreich mit backtrace () und backtrace_symbols () tun. Jetzt möchte ich zusätzlich die Zeilennummern des Absturzes bekommen. Wie macht es das?
Ich habe Hilfe von
genommenСсылка und Ссылка um einen Beispielcode zu erstellen, der zeigt, wie Sie dies erreichen können.
Im Grunde geht es darum, einen Stack-Backtrace innerhalb eines Signal-Handlers zu setzen und ihn alle "schlechten" Signale zu erfassen, die Ihr Programm empfangen kann (SIGSEGV, SIGBUS, SIGILL, SIGFPE und dergleichen). Auf diese Weise, wenn Ihr Programm unglücklicherweise abstürzt und Sie es nicht mit einem Debugger ausgeführt haben, können Sie einen Stack-Trace bekommen und wissen, wo der Fehler passiert ist. Diese Technik kann auch verwendet werden, um zu verstehen, wo Ihr Programm läuft, falls es nicht mehr reagiert ...
Im folgenden Code wird das externe Programm addr2line für jede Adresse in der Ablaufverfolgung ausgeführt, um es in einen Dateinamen umzuwandeln eine Zeilennummer.
Der folgende Quellcode druckt Zeilennummern für alle lokalen Funktionen. Wenn eine Funktion aus einer anderen Bibliothek aufgerufen wird, sehen Sie möglicherweise ein paar von:: 0 anstelle von Dateinamen.
%Vor%Dieser Code sollte wie folgt kompiliert werden: gcc sighandler.c -o sighandler -rdynamic
Das Programm gibt aus:
%Vor% Dies ist nur möglich, wenn das Programm mit Debuginformationen kompiliert wurde (d. h. mit gcc -Wall -g
oder mit g++ -Wall -g
). Ohne -g
enthält die ausführbare Datei keine Quellzeileninformationen. Und wenn Sie gcc
verwenden, können Sie mit beiden Optimierungen & amp; Debugging-Informationen (z. B. g++ -Wall -g -O2
), aber manchmal wäre der Zeilenstandort "überraschend".
Das Flag -Wall
fordert GCC auf, alle Warnungen anzuzeigen. Es ist sehr nützlich (daher meine Empfehlung, es zu verwenden), aber nicht in Verbindung mit -g
oder Debugging-Informationen.
Um die Zeilennummer zu extrahieren, wäre es am einfachsten, einen gdb
-Prozess aufzuteilen. Alternativ könnten Sie die Debugging-Informationen (im DWARF -Format) abrufen und analysieren, vielleicht mit libdwarf
aus dem ELF Werkzeugkette . Ich bin mir nicht sicher, ob es die Mühe wert ist ...
Um nur das Backtrace zu erhalten, können Sie Ihr Programm einfach durch gdb
vielleicht als gdb --args yourprogram itsarguments
...
Sie könnten auch die libbacktrace aus einem aktuellen GCC verwenden, der Ihr Problem lösen soll Problem (es "interpretiert" das DWARF-Format der aktuellen ausführbaren Datei, das Sie mit g++ -O -g
kompilieren würden).