kgdbを用いたカーネルデバッグ環境の構築
kgdbはLinux 2.6.26 から統合されたカーネルのデバッグ機能です。使った感じとしては、gdbサーバをカーネルが提供しているような雰囲気です。カーネルモジュールを書いていて厄介なバグに出会ったので、導入してみるに至りました。以下ではその導入方法について述べます。
おおまかな手順
おおかまな手順は以下の通りです。
kgdbをサポートしているカーネルを用意する
kernel.orgなどから2.6.26以降のカーネルを落としてきて、make oldconfigした上でmake menuconfigし、Kernel hackingの項目を開き、kgdbをオンにしてカーネルをビルドします。多くの場合、以下のようなフローになるでしょう:
$ sudo cp /boot/config-`uname -r` /usr/src/linux-2.6.28.8/.config $ cd /usr/src/linux-2.6.28.8 $ sudo make oldconfig $ sudo make menuconfig
[Kernel Hacking] > [Kgdb] にチェックを入れて再コンパイルしてください。
boot時オプションでkgdbを使うように指示する
kernel行の末尾に、kgdbを使うようにオプションをつけます。
kernel ... kgdboc=ttyS0,115200 kgdbwait
再起動すると、kgdbの入力待ちとなります。
リモートからターゲットにつないでみる
ターゲットのvmlinuxを読み込み、$はプロンプトです。printkにブレークポイントをしかけて動作させてみましょう。
$ gdb (gdb) file vmlinux (gdb) target remote /dev/ttyS0 接続応答メッセージ (gdb) b printk (gdb) c
初期メッセージが読み込まれる寸前でブレークするはずです。step実行するなり何なりして遊びましょう。
後で読み込まれるシンボルへのアクセス
kgdbでは、後に読み込まれたシンボルへのアクセスができるようです。仮に、最初
(gdb) b sample_module_init
としてブレークポイントを設定すると、「そんなシンボルはないけど共有ライブラリがロードされたときにブレークするように設定するかい?」と聞いてきます。yesとすると、そのシンボルを通過したときにブレークする...はず?*1
まとめ
カーネルデバッガというと、設定がとても難しそうなイメージがありますが、意外と簡単にできることがわかったかと思います。是非皆さんも挑戦してみてください:D