gdbとは
実行中のプログラムの内部で何が起こっているのか、
プログラムがクラッシュしたときに何が起こっていたのかを知るためのツールである。
実際のバグを発見できるようにするために4つのこと(さらに、これらを支援するために他のことも)行う。
- プログラムを、その動作に影響を与える可能性のある様々なことを指定して起動する
- 指定された条件が成立したときにプログラムを停止する
- 停止したときにプログラムが何を行っていたかを調べる
- プログラムの内部を変更することによって、 1つのバグの影響を試験的に修正して、ほかのバグについて調べる
gdbでは C, C++, Modula-2 などで書かれたプログラムのデバッグが行なえる。
プログラムを実行中のマシンとは別のマシンからデバッグを行うことである。
オペレーティング・システムのカーネルのデバッグや、
フル機能を持つデバッガを実行するのに十分な機能を持つ汎用的なオペレーティング・システムを持たない
小規模なシステムでのデバッグを行う場合にリモートデバッグを行う。
1台はデバッグ環境のためのホストで, すべてのソースとすべてのシンボルを含んだバイナリのコピーを持っている。
もう 1台はターゲットマシンで, 同一のプログラムのコピー (ただしデバッグ情報は 取り除いてあるもの)
を単に実行するためのものが必要になる。
通常は2台のマシン間での通信を行うためにはスタブをプログラムソース含める必要がある。
しかし、gdbserverを使用することによってスタブをリンクすることなくリモートでバッグができる。
カーネルをデバッグするにはコンフィグの”CONFIG_DEBUG_INFO”を有効にし、再コンパイルを行う。
再コンパイルしたカーネルを利用し以下の用にgdbを実行すると、
prompt> gdb vmlinux
GNU gdb Red Hat Linux (6.3.0.0-1.122rh)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "ppc-redhat-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".
(gdb)
のようにgdbのプロンプト画面に移る。
ここでシステムコールsys_openでbreakpointを作成してみる
(gdb) break sys_open
Breakpoint 1 at 0xc0080bec: file fs/open.c, line 1107.
そして実行してみる
(gdb) run
Starting program: /usr/src/redhat/SOURCES/linux-2.6.17.debug/vmlinux
Program terminated with signal SIGKILL, Killed.
The program no longer exists.
You can't do that without a process to debug.
するとsys_openでブレイクする前にプログラムが止まってしまった。
カーネルをリモートデバッグしてみる
ターゲットとなるマシンでgdbserverを実行する。
ここではFedora Core 5が動いているiBookでgdbserverを実行する。
prompt> gdbserver host:9321 vmlinux
[root@nw0436 linux-2.6.17.debug]# gdbserver host:9321 vmlinux
Process vmlinux created; pid = 31896
Child terminated with signal = 9
Listening on port 9321
子プロセスが終了したとメッセージが出たが、そのまま作業を続けることにする。
次にホストとなるマシンでgdb実行し、リモートデバッグをする。
SUSE Linuxが動いている別のiBookからgdbを実行し、ターゲットに接続してみた。
(gdb) target remote 133.13.54.206:9321
Remote debugging using 133.13.54.206:9321
Remote communication error: 接続が相手からリセットされました。
と、相手側から接続が遮断された。
考察
ローカルでカーネルでgdbを実行しsys_openでブレイクポイントを作成したが、
sys_openが呼び出される前にプログラムが終了した原因は、カーネルをただは実行
しただけではシステムコールsys_openは呼び出されない為だと思われる。
なんらかの操作でシステムコールを呼び出せる方法を見つければうまくsys_openでブレイクしてくれるものと思われる。
リモートデバッグで接続されなかったはのgdbserverを実行した段階で、子プロセスが終了しているのに問題があると思われる。kernelのリモートデバッグの方法としてkgdbを使用した方法がいくつか紹介さ、「gdb -k」とするとkgdbモードになるらしいが、今回使用したFedoraとSUSEにはgdbに「-k」が存在しなかった。