Unix で addr2line コマンドを使用しようとしていますが、毎回 ??:0 と同じ出力が得られます。としてコマンドを与えていaddr2line -e a.out 0x4005BDC
ます。このa.out実行可能ファイルをvalgrind
ツールで実行してメモリリークを見つけたときに、このアドレスを取得しました。-g
ソースコードもオプションでコンパイルしました。
4 に答える
addr2line の代わりに gdb を使用してメモリ アドレスを調べることもできます。実行可能ファイルを gdb にロードし、そのアドレスに格納されているシンボルの名前を出力します。16 記号テーブルの調査.
(gdb) info symbol 0x4005BDC
仮想アドレス(VA)ではなく、addr2lineへのオフセットを指定する必要があります。おそらく、アドレス空間のランダム化をオフにしている場合は、完全なVAを使用できますが、最近のほとんどのOSでは、アドレス空間は新しいプロセスのためにランダム化されています。
0x4005BDC
valgrindによるVAを指定して、メモリ内のプロセスまたはライブラリのベースアドレスを見つけます。/proc/<PID>/maps
これを行うには、プログラムの実行中にファイルを調べます。関心のある行はプロセスのセグメントであり、アクセス許可とプログラムまたはライブラリの名前でtext
識別できます。r-xp
ベースVAがであるとしましょう0x0x4005000
。次に、valgrindが提供するVAとベースVAの違いを見つけます0xbdc
。次に、それをadd2lineに提供します。
addr2line -e a.out -j .text 0xbdc
そして、それがあなたの行番号を取得するかどうかを確認してください。
まさにその使い方です。ただし、アドレスがソース コード内の何かに直接対応していない可能性があります。
例えば:
$ 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
main
私の場合のアドレスです。0x400408
も有効な関数アドレスですa.out
が、これは GCC によって生成/インポートされたコードであり、デバッグ情報はありません。(この場合、__libc_csu_init
. で実行可能ファイルのレイアウトを確認できますreadelf -a your_exe
。)
その他の場合addr2line
は、デバッグ情報を持たないライブラリを含めている場合です。
-f
関数名を表示するオプションを追加してみてください:
addr2line -f -e a.out 0x4005BDC