次のようなストリップされたアプリケーションによって生成されたスタックトレースがあります。
*** Check failure stack trace: ***
@ 0x7f0e442d392d (unknown)
@ 0x7f0e442d7b1f (unknown)
@ 0x7f0e442d7067 (unknown)
@ 0x7f0e442d801d (unknown)
@ 0x7f0e457c55e6 (unknown)
@ 0x7f0e457c5696 (unknown)
@ 0x4e8765 (unknown)
@ 0x4a8b43 (unknown)
@ 0x7f0e43197ced (unknown)
@ 0x4a6889 (unknown)
そして、実行可能ファイルとそのすべてのライブラリ(デバッグ情報付きでコンパイルされたもの)のストリップされていないバージョンがあります。しかし、どうすればアドレスをファイルと行番号に変換できますか?
ここに私が試したものがあります:
gdb
set solib-absolute-prefix /path/to/non-stripped/edition/of/root/filesystem/sysroot/
file /path/to/non-stripped/edition/of/root/filesystem/sysroot/usr/bin/my-buggy-app
info line *0x7f0e457c5696
ファイルコマンドを入力すると、使用されているすべてのライブラリではなく、ファイルからシンボルのみが読み込まれます。これを行う方法はありますか?
「情報行」コマンドは言う:
アドレス0x7f0e442d801dの行番号情報はありません
アドレスが共有ライブラリの1つにあるためだと思いますが、どのライブラリにあるのかをどのように知ることができますか?
しかし、どうすればアドレスをファイルと行番号に変換できますか?
メインの実行可能ファイル(0x4e8765
などのアドレス)の場合:
addr2line -e /path/to/non-stripped/.../my-buggy-app \
0x4a6889 0x4a8b43 0x4e8765
実際には、上記のすべてのアドレスから5
(CALL
命令の通常の長さ)を差し引くことができます。
共有ライブラリのアドレスについては、ライブラリのロードアドレスを知る必要があります。
アプリケーションがcore
ファイルを生成した場合、(gdb) info shared
はライブラリがロードされた場所を通知します。
コアファイルを取得せず、アプリケーションが必要なマッピングを印刷しなかった場合、
0x4e8760
の実行可能ファイルのコードを見てください-それは何らかの関数へのCALL
命令であるべきです。次に、その関数がどのライブラリにあるかを調べ、ライブラリ内でそのアドレスを見つけます(nm
を使用)。運がよければ、そのアドレスは0xNc56NN
の近くにあります。これで、0x7f0e457NNNNNN
にあるライブラリのロードアドレスを推測できます。 0x7f0e457c55e1
についても繰り返します。0x7f0e442dNNNN
でライブラリのロードアドレスを確認できます。OPごとに、アドレスからコードのソース行を見つけるためのGDBのコマンドは次のとおりです。
info line *0x10045740
編集:特定の条件下では機能しない「情報シンボル0x10045740」を置き換えました(@ Thomasa88に感謝)。