はじめに

先日,会社の同僚と話していた時のこと.

「えっ,gdb ってソースコードデバッグできるのか!!」

という同僚のセリフを聞いてショックを受けました. アセンブラレベルでのデバッグしかできないと思ってたようです.

というわけで,「はじめての gdb」あたりのようなことを書いてみようかな,と.

デバッガで何ができるのか

そもそも「デバッガってなに?おいしいの?」というような向きに.

プログラムのデバッグ

debug-ger という名前のとおりの使い方です. プログラムを作っている時にその プログラムを実行させてみて,実行途中の状態を調べることができます.

プログラムの解析

他人が作ったプログラムの場合には,「とりあえず実行させてみて,このときはここで処理を行っているのか」というあたりを調べることができます :)

http://jr0bak.homelinux.net/~imai/linux/jdmouse-2.0.0.tar.gz の中の xzoom というプログラムを使ってみます.

コンパイル

gcc を呼び出す時に -g オプションを付けてコンパイルします. つまり,コマンドラインから gcc を直接実行する場合は

$ gcc -g foo.c

のようにします.

Makefile では

CFLAGS += -g

という行を追加してやれば OK です. ちなみに,jdmouse の Makefile では既にこのオプションが追加されているので,変更は不要です. そのまま make してみましょう. src ディレクトリの下に xzoom という実行プログラムが出来上がります.

gdb の起動

xzoom をターゲットプログラムとして gdb を起動します. src ディレクトリに降りて

$ gdb xzoom

と入力してみましょう.

$ gdb xzoom
GNU gdb 6.3-debian
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 "i386-linux"...Using host libthread_db library "/lib/
tls/libthread_db.so.1".

(gdb) 

と,gdb のプロンプトが表示されます.

この状態では,ターゲットプログラムは,まだ実行されていません.

プログラムの表示

list コマンドを使用します.

(gdb) list
26              int fd;
27              int key = KEY_KPPLUS;
28              const int codetable[] = { KEY_RIGHTCTRL,
29                                        KEY_RIGHTALT,
30                                        KEY_KPPLUS,
31                                        KEY_KPMINUS,
32                                        -1 };
33
34              /* argument check */
35              if ( argc == 2 ) {

えーと,これは main() 関数の先頭ですね.

引数に関数名を指定すると,その関数(のちょっと手前)から表示します.

(gdb) list usage
12      #include "uinput.h"
13      #include <stdio.h>
14      #include <stdlib.h>
15
16      void usage ( void )
17      {
18              fprintf ( stderr,
19                        "xzoom: zoom/unzoom X screen.\n"
20                        "\n"
21                        "usage: xzoom [+|-]\n" );

ブレークポイント

「デバッガ上でのプログラムの実行がそこに差しかかったら,一時停止する」プログラム上の場所を指定することができます. このようなポイントをブレークポイントと呼びます.

で,このブレークポイントの設定のしかたは簡単. まず,list コマンドで,調べたい関数を表示します.

(gdb) list usage
12      #include "uinput.h"
13      #include <stdio.h>
14      #include <stdlib.h>
15
16      void usage ( void )
17      {
18              fprintf ( stderr,
19                        "xzoom: zoom/unzoom X screen.\n"
20                        "\n"
21                        "usage: xzoom [+|-]\n" );

そして

(gdb) break 18

と入力すると

Breakpoint 1 at 0x8048506: file xzoom.c, line 18.

と表示され,ブレークポイントの1番に設定されます.

また,

(gdb) break usage
Note: breakpoint 1 also set at pc 0x8048506.
Breakpoint 2 at 0x8048506: file xzoom.c, line 18.

のように,関数名を指定すると,関数の先頭にブレークポイントが設定されます. (ここで Note: と出ているのは,同じ場所に2つのブレークポイントが設定されてしまったためです.)

現在設定されているブレークポイントの一覧を確認するには

(gdb) info breakpoints 
Num Type           Disp Enb Address    What
1   breakpoint     keep y   0x08048506 in usage at xzoom.c:18
2   breakpoint     keep y   0x08048506 in usage at xzoom.c:18

でできます.

既に設定されているブレークポイントの削除は

(gdb) delete 1

で,1番のブレークポイントが削除されます.

ターゲットプログラムの実行

run コマンドでターゲットプログラムを実行します. run コマンドの引数は,ターゲットプログラムへ引数として渡されます. つまり

(gdb) run -h

と入力すると,この例の場合では

$ xzoom -h

と引数を指定されたのと同等です.

それでは,実行してみましょう.

(gdb) run -h
Starting program: /home/imai/jdmouse-2.0.0/src/xzoom -h

Breakpoint 1, usage () at xzoom.c:18
18              fprintf ( stderr,

先ほど指定したブレークポイントで実行が中断されました.

(今日はここまで)


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2005-11-08 (火) 02:27:35 (6766d)