Ich versuche, den Befehl addr2line in Unix zu verwenden, aber jedes Mal gibt er die gleiche Ausgabe wie ??:0 aus. Ich gebe Befehle als addr2line -e a.out 0x4005BDC
. Ich habe diese Adresse erhalten, während ich diese ausführbare a.out-Datei mit ausgeführt habe valgrind
Werkzeug, um das Speicherleck zu finden. Ich habe auch den Quellcode mit kompiliert -g
Möglichkeit.
Wie verwende ich den addr2line-Befehl unter Linux?
Prak
Sie können auch gdb anstelle von addr2line verwenden, um die Speicheradresse zu untersuchen. Ausführbare Datei in gdb laden und den Namen eines Symbols ausgeben, das unter der Adresse gespeichert ist. 16 Untersuchen der Symboltabelle.
(gdb) info symbol 0x4005BDC
-
Gute Idee. Auch das Ausführen des Programms in gdb mit einem Haltepunkt an dieser Adresse und das Abrufen des Backtrace könnte gute Informationen darüber geben, was genau dort passiert.
– Matte
4. Oktober 2011 um 14:08 Uhr
-
Siehe auch (gdb) Infozeile * 0x4005BDC
– Benutzer47559
4. Oktober 2011 um 15:01 Uhr
-
Die (Bibliotheks-) Codeadresse wäre gleich oder unterschiedlich, zwischen dem Kompilieren mit dem Flag “-g” und ohne das Flag ?
– Windjäger
18. März 2016 um 22:27 Uhr
Sie müssen eine angeben versetzt an addr2line, keine virtuelle Adresse (VA). Wenn Sie die Adressraum-Randomisierung deaktiviert hätten, könnten Sie vermutlich eine vollständige VA verwenden, aber in den meisten modernen Betriebssystemen werden Adressräume für einen neuen Prozess randomisiert.
Angesichts der VA 0x4005BDC
Finden Sie mit valgrind die Basisadresse Ihres Prozesses oder Ihrer Bibliothek im Speicher. Tun Sie dies, indem Sie die untersuchen /proc/<PID>/maps
Datei, während Ihr Programm läuft. Die interessante Linie ist die text
Segment Ihres Prozesses, das durch die Berechtigungen identifizierbar ist r-xp
und den Namen Ihres Programms oder Ihrer Bibliothek.
Nehmen wir an, dass die Basis-VA ist 0x0x4005000
. Dann würden Sie den Unterschied zwischen der von Valgrind gelieferten VA und der Basis-VA finden: 0xbdc
. Geben Sie das dann an add2line weiter:
addr2line -e a.out -j .text 0xbdc
Und sehen Sie, ob Ihnen das Ihre Zeilennummer bringt.
-
Moment mal, welche Offsets? Nimmt addr2line nicht nur Adressen von symtab (oder dyntab)?
– Alexander Malachow
13. März 2013 um 10:59 Uhr
Genau so benutzt man es. Es besteht jedoch die Möglichkeit, dass die Adresse, die Sie haben, nicht direkt mit etwas in Ihrem Quellcode übereinstimmt.
Zum Beispiel:
$ cat t.c
#include <stdio.h>
int main()
{
printf("hello\n");
return 0;
}
$ gcc -g t.c
$ addr2line -e a.out 0x400534
/tmp/t.c:3
$ addr2line -e a.out 0x400550
??:0
0x400534
ist die Adresse von main
in meinem Fall. 0x400408
ist auch eine gültige Funktionsadresse in a.out
, aber es ist ein Stück Code, der von GCC generiert/importiert wurde und keine Debug-Informationen enthält. (In diesem Fall, __libc_csu_init
. Sie können das Layout Ihrer ausführbaren Datei mit sehen readelf -a your_exe
.)
Andere Zeiten, wenn addr2line
schlägt fehl, wenn Sie eine Bibliothek einschließen, die keine Debug-Informationen enthält.
-
In meinem Code verwende ich die Bibliothek pthread und libconfing. Ich weiß nicht, ob diese Bibliotheken Debug-Informationen haben oder nicht.
– Prak
4. Oktober 2011 um 15:41 Uhr
Penghe Geng
Versuchen Sie, die hinzuzufügen -f
Option zum Anzeigen der Funktionsnamen:
addr2line -f -e a.out 0x4005BDC