Gibt es eine Möglichkeit, Stack-Trace mit Zeilennummer aus einer Linux-Release-Binärdatei zu dumpen?

8

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?

    
Anirudh Jayakumar 28.02.2013, 06:39
quelle

3 Antworten

12

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%     
Saqlain 28.02.2013 07:39
quelle
2

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 ...

ausführen

Zusätze

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).

    
Basile Starynkevitch 28.02.2013 06:43
quelle
0

Wie Saqlain sagte, kann addr2line verwendet werden, um die Zeilennummer zu erhalten.

Wenn eine Bibliothek bevorzugt wird, sehen Sie sich das LPT-Paket an. Anweisungen zur Installation finden Sie hier . LPT stützt sich auf die bfd-Bibliothek.

    
toddwz 18.02.2015 19:24
quelle

Tags und Links