web-dev-qa-db-ja.com

Linuxカーネルパニックを読み取り、理解、分析、デバッグする方法

次の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コードを確認するにはどうすればよいですか?
  • パニックの内容を解釈する方法は?
40
0x90

これは単なる通常のバックトレースであり、これらの関数は逆の順序で呼び出されます(最初に呼び出された関数は、前の関数によって呼び出されました)。

_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)

43
iabdalkader

_addr2line_の2つの選択肢があります。適切なターゲットのツールチェーンがあると仮定すると、次のいずれかを実行できます。

objdumpを使用

  1. カーネルルートディレクトリの下でvmlinuxまたは_.ko_ファイルを探し、オブジェクトファイルを逆アセンブルします。

    _objdump -dS vmlinux > /tmp/kernel.s
    _
  2. 生成されたアセンブリファイル_/tmp/kernel.s_を開きます。 vimなどのテキストエディターを使用します。 _unwind_backtrace+0x0/0xf8_に移動します。つまり、_unwind_backtrace_ + offsetのアドレスを検索します。最後に、ソースコードの問題のある部分を特定しました。

gdbを使用

IMO、さらにエレガントなオプションは、唯一のgdbを使用することです。ホストマシンに適切なツールチェーンがあると仮定します。

  1. _gdb <path-to-vmlinux>_を実行します。
  2. Gdbのプロンプトで実行します:list *(unwind_backtrace+0x10)

追加情報については、以下をチェックアウトできます。

  1. カーネルデバッグのコツ
  2. Gdbを使用したLinuxカーネルのデバッグ
21
0x90

unwind_backtrace+0x0/0xf8+0x0/0xf8は何を表していますか?

最初の数字(+0x0)は関数の先頭からのオフセット(この場合はunwind_backtrace)です。 2番目の数字(0xf8)は、関数の全長です。これらの2つの情報を考えると、障害が発生した場所について既に把握している場合、これは疑いを確認するのに十分かもしれません(機能のどこまで進んでいるかを(おおよそ)知ることができます)。

対応する命令の正確なソース行を取得するには(通常は予測よりも優れています)、addr2lineまたは他の回答で他のメソッドを使用します。

13
mgalgs