56

Unix で addr2line コマンドを使用しようとしていますが、毎回 ??:0 と同じ出力が得られます。としてコマンドを与えていaddr2line -e a.out 0x4005BDCます。このa.out実行可能ファイルをvalgrindツールで実行してメモリリークを見つけたときに、このアドレスを取得しました。-gソースコードもオプションでコンパイルしました。

4

4 に答える 4

36

addr2line の代わりに gdb を使用してメモリ アドレスを調べることもできます。実行可能ファイルを gdb にロードし、そのアドレスに格納されているシンボルの名前を出力します。16 記号テーブルの調査.

(gdb) info symbol 0x4005BDC 
于 2011-10-04T13:45:13.747 に答える
24

仮想アドレス(VA)ではなく、addr2lineへのオフセットを指定する必要があります。おそらく、アドレス空間のランダム化をオフにしている場合は、完全なVAを使用できますが、最近のほとんどのOSでは、アドレス空間は新しいプロセスのためにランダム化されています。

0x4005BDCvalgrindによるVAを指定して、メモリ内のプロセスまたはライブラリのベースアドレスを見つけます。/proc/<PID>/mapsこれを行うには、プログラムの実行中にファイルを調べます。関心のある行はプロセスのセグメントであり、アクセス許可とプログラムまたはライブラリの名前でtext識別できます。r-xp

ベースVAがであるとしましょう0x0x4005000。次に、valgrindが提供するVAとベースVAの違いを見つけます0xbdc。次に、それをadd2lineに提供します。

addr2line -e a.out -j .text 0xbdc

そして、それがあなたの行番号を取得するかどうかを確認してください。

于 2011-10-04T15:35:49.620 に答える
13

まさにその使い方です。ただし、アドレスがソース コード内の何かに直接対応していない可能性があります。

例えば:

$ 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

0x400534main私の場合のアドレスです。0x400408も有効な関数アドレスですa.outが、これは GCC によって生成/インポートされたコードであり、デバッグ情報はありません。(この場合、__libc_csu_init. で実行可能ファイルのレイアウトを確認できますreadelf -a your_exe。)

その他の場合addr2lineは、デバッグ情報を持たないライブラリを含めている場合です。

于 2011-10-04T13:40:21.423 に答える
12

-f関数名を表示するオプションを追加してみてください:

addr2line -f -e a.out 0x4005BDC
于 2015-04-24T14:59:14.933 に答える