Wie verwende ich den addr2line-Befehl unter Linux?

Lesezeit: 3 Minuten

Benutzeravatar von Prak
Prak

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.

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

Benutzeravatar von Penghe Geng
Penghe Geng

Versuchen Sie, die hinzuzufügen -f Option zum Anzeigen der Funktionsnamen:

addr2line -f -e a.out 0x4005BDC

1411870cookie-checkWie verwende ich den addr2line-Befehl unter Linux?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy