->back to toppage

課題内容 - Level.3 -

Linux には、リモートデバッグという機能がある。gdb のリモートデバッグに関して調べよ。
これは、二つのコンピュータ(VMwareのような仮想コンピュータでも良い)接続して、 片方から片方のkernel(などのプログラム)をデバッグする方法である。

これを動作させるためには、Linux のカーネルを作り直す必要があると思われる。
リモートデバッグオプションを有効にし、実際に、動作させてみよ。
いくつかのsystem callをリモートデバッグのブレークポイントの対象にし、実際に止めて観察せよ。


報告内容

gdbとは

実行中のプログラムの内部で何が起こっているのか、 プログラムがクラッシュしたときに何が起こっていたのかを知るためのツールである。
  実際のバグを発見できるようにするために4つのこと(さらに、これらを支援するために他のことも)行う。
  1. プログラムを、その動作に影響を与える可能性のある様々なことを指定して起動する
  2. 指定された条件が成立したときにプログラムを停止する
  3. 停止したときにプログラムが何を行っていたかを調べる
  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」が存在しなかった。



参考文献



<-previous problem    go to top    next problem->