Linuxアプリケーションがクラッシュすると、ログに次のような行が生成されます。
0000000でのセグメンテーション違反rip00003f32a823rsp000123ade323エラー4
それらのripおよびrspアドレスは何ですか?それらを使用して問題を特定するにはどうすればよいですか?それらは「objdump」または「readelf」出力の何かに対応していますか?私のプログラムがそのシンボルを(gdbを使用して使用できる別のファイルに)削除する場合に役立ちますか?
Linuxアプリケーションがクラッシュすると、ログに次のような行が生成されます。
0000000でのセグメンテーション違反rip00003f32a823rsp000123ade323エラー4
それらのripおよびrspアドレスは何ですか?それらを使用して問題を特定するにはどうすればよいですか?それらは「objdump」または「readelf」出力の何かに対応していますか?私のプログラムがそのシンボルを(gdbを使用して使用できる別のファイルに)削除する場合に役立ちますか?
さて、リップポインタはクラッシュの原因となった命令を教えてくれます。マップファイルで検索する必要があります。
マップファイルには、関数とその開始アドレスのリストがあります。アプリケーションをロードすると、ベースアドレスにロードされます。ripポインタ-ベースアドレスはマップファイルアドレスを提供します。次に、マップファイルを検索して、リップポインターよりわずかに低いアドレスで始まり、リスト内でより高いアドレスの関数が続く関数を検索すると、クラッシュした関数が見つかります。
そこから、コードのどこが間違っているのかを特定する必要があります。それほど楽しいことではありませんが、少なくとも、出発点になります。
編集:「segfaultat」ビットは、NULLポインターを逆参照したことを示しています。rspは、現在のスタックポインタです。残念ながら、おそらくそれほど有用ではありません。メモリダンプを使用すると、関数のどこに到達したかをより正確に把握できる可能性がありますが、最適化されたビルドのどこにいるかを正確に把握するのは非常に難しい場合があります。
私もエラーになりました。私が見たとき:
probe.out[28503]: segfault at 0000000000000180 rip 00000000004450c0 rsp 00007fff4d508178 error 4
probe.out は libavformat (ffmpeg) を使用したアプリです。分解しました。
objdump -d probe.out
リップは、命令が実行される場所です。
00000000004450c0 <ff_rtp_queued_packet_time>:
4450c0: 48 8b 97 80 01 00 00 mov 0x180(%rdi),%rdx
44d25d: e8 5e 7e ff ff callq 4450c0 <ff_rtp_queued_packet_time>
最後に、関数ff_rtp_queued_packet_timeでアプリがクラッシュしたことを発見しました
PS。住所が正確に一致しない場合もありますが、ほぼ一致しています。