次のLinuxカーネルダンプスタックトレースを検討してください。panic("debugging a linux kernel panic");
を呼び出すことにより、カーネルソースコードからパニックを引き起こすことができます。
[<001360ac>] (unwind_backtrace+0x0/0xf8) from [<00147b7c>] (warn_slowpath_common+0x50/0x60)
[<00147b7c>] (warn_slowpath_common+0x50/0x60) from [<00147c40>] (warn_slowpath_null+0x1c/0x24)
[<00147c40>] (warn_slowpath_null+0x1c/0x24) from [<0014de44>] (local_bh_enable_ip+0xa0/0xac)
[<0014de44>] (local_bh_enable_ip+0xa0/0xac) from [<0019594c>] (bdi_register+0xec/0x150)
unwind_backtrace+0x0/0xf8
で+0x0/0xf8
は何を表していますか?unwind_backtrace+0x0/0xf8
のCコードを確認するにはどうすればよいですか?これは単なる通常のバックトレースであり、これらの関数は逆の順序で呼び出されます(最初に呼び出された関数は、前の関数によって呼び出されました)。
_unwind_backtrace+0x0/0xf8
warn_slowpath_common+0x50/0x60
warn_slowpath_null+0x1c/0x24
ocal_bh_enable_ip+0xa0/0xac
bdi_register+0xec/0x150
_
_bdi_register+0xec/0x150
_は、シンボル+オフセット/長さです カーネルOopsの理解 およびカーネルOOPSのデバッグ方法に関する詳細があります。 カーネルのデバッグ に関するこの素晴らしいチュートリアルもあります
注:以下でEugeneが提案しているように、最初に addr2line を試してみたいと思うかもしれません。
addr2line -e vmlinux_with_debug_info 0019594c(+offset)
_addr2line
_の2つの選択肢があります。適切なターゲットのツールチェーンがあると仮定すると、次のいずれかを実行できます。
objdump
:を使用
カーネルルートディレクトリの下でvmlinux
または_.ko
_ファイルを探し、オブジェクトファイルを逆アセンブルします。
_objdump -dS vmlinux > /tmp/kernel.s
_
生成されたアセンブリファイル_/tmp/kernel.s
_を開きます。 vim
などのテキストエディターを使用します。 _unwind_backtrace+0x0/0xf8
_に移動します。つまり、_unwind_backtrace
_ + offset
のアドレスを検索します。最後に、ソースコードの問題のある部分を特定しました。
gdb
:を使用
IMO、さらにエレガントなオプションは、唯一のgdb
を使用することです。ホストマシンに適切なツールチェーンがあると仮定します。
gdb <path-to-vmlinux>
_を実行します。list *(unwind_backtrace+0x10)
。追加情報については、以下をチェックアウトできます。
unwind_backtrace+0x0/0xf8
で+0x0/0xf8
は何を表していますか?
最初の数字(+0x0
)は関数の先頭からのオフセット(この場合はunwind_backtrace
)です。 2番目の数字(0xf8
)は、関数の全長です。これらの2つの情報を考えると、障害が発生した場所について既に把握している場合、これは疑いを確認するのに十分かもしれません(機能のどこまで進んでいるかを(おおよそ)知ることができます)。
対応する命令の正確なソース行を取得するには(通常は予測よりも優れています)、addr2line
または他の回答で他のメソッドを使用します。