gdbを用いたデバッグ


gdbとは

 gdbは The GNU Project Debuggerのことです。 デバッグのためのツールです。 プログラムがエラー終了するが、どこが悪いのかわからない… というような時に便利です。


準備

デバッグ対象プログラムのコンパイル

 コンパイルしたプログラムにデバッグ情報を含めておくと、 デバッガでプログラムのソースを参照できるなど、 デバッグが非常に楽になります。 gccやUNIXのccでは、コンパイル時に「-g」オプションを付加すると デバッグ情報を生成します。 最適化オプション「-O」と デバッグオプション「-g」の両方は 同時に指定できないコンパイラもあるので注意してください。 gccは同時に指摘できます。 なお、FreeBSDやRedHat Linuxのccの正体はgccなので、 「-O」と「-g」を同時に指定できます。

 makeでコンパイルしている場合には、 「-g」オプションを付加するために Makefileを書き換えなければならない場合があります。

    CFLAGS = -g …
    cc -c -g …
のようになっている場合は既にデバッグオプションが指定されています。 そうでない場合にはMakefileの変更と再コンパイルが必要です。 変更方法はMakefileの書き方に依存します。 CFLAGSへの代入があれば、 そこに-gを追加すると良いでしょう。 なければ、自分でCFLAGSを定義する場合や、 ccCCのところに書き加える場合があります。

 単にMakefileを書き換えてmakeしただけでは、 全く再コンパイルされない可能性があります。 バイナリはソースより新しいからです。 デバッグしたいプログラムのバイナリと中間ファイル (*.oなど) を削除してから 再コンパイルします。

 デバッグオプションを付けずにコンパイルしたプログラムを gdbでデバッグしようとした場合には、 デバッガ起動時のメッセージに

    (no debugging symbols found)...
のようなものが含まれます。 この場合は再コンパイルした方が良いでしょう。

core

 UNIXでは、プログラムが異常終了した場合に、 プログラムが使用していたメモリの内容等をファイルに書き出す機能があります。 このファイルをcoreまたはcore dumpと呼びます。 ファイル名は必ず「core」になるUNIXもありますが、 FreeBSDのように「プログラム名.core」になる OSもあります。

 gdbを用いたデバッグ方法の一つに、coreを用いる方法があります。 プログラムがエラー終了した後から解析できるので便利です。 ただし、そのためには、coreを生成するように設定しておく必要があります。 どのような設定になっているのかを確認するには、

    limit coredumpsize
を実行します (単にlimitでも良い)。この結果が
    coredumpsize    unlimited
であればcoreを生成します。もしも、
    coredumpsize    0 kbytes
のようにゼロであれば、coreを全く生成しません。 デバッガを使う意志が無い場合には、この方がディスクの節約になります。 coreを生成しない設定になっているか、あるいは、 サイズが小さ過ぎると思われる場合には、
    limit coredumpsize unlimited
を実行します。 毎回実行するのが面倒な場合には、 ~/.cshrc (csh系) や~/.profile (bsh系) に書いておくと良いでしょう。


デバッグ方法

 3通りあります。 以下の実行例では、下線部分が自分で入力するところです。 なお、表示内容は実行環境や設定によって異なります。

coreを使う

 エラー終了した後から解析する方法です。

    gdb プログラム coreファイル
を実行します。 デバッガを起動すると、発生したエラーコード、 その時に実行していた部分のソースなどを表示します。 下記は実行例です。
pegasus{hirano}[93]: cat test.c
main()
{
        int x[10];

        x[10000] = 0;
}

pegasus{hirano}[94]: cc -g test.c
pegasus{hirano}[95]: ./a.out
Bus error (core dumped)
pegasus{hirano}[96]: gdb a.out a.out.core
GNU gdb 4.18 (FreeBSD)
Copyright 1998 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-unknown-freebsd"...Deprecated bfd_read called at /usr/src/gnu/usr.bin/binutils/gdb/../../../../contrib/gdb/gdb/dbxread.c line 2627 in elfstab_build_psymtabs
Deprecated bfd_read called at /usr/src/gnu/usr.bin/binutils/gdb/../../../../contrib/gdb/gdb/dbxread.c line 933 in fill_symbuf

Core was generated by `a.out'.
Program terminated with signal 10, Bus error.
Reading symbols from /usr/lib/libc.so.4...done.
Reading symbols from /usr/libexec/ld-elf.so.1...done.
#0  main () at test.c:5
5               x[10000] = 0;
(gdb) 

デバッガ上でプログラムを実行する

 最初からデバッガ上でプログラムを実行します。 まず、

    gdb プログラム
を実行します。 (gdb) というプロンプトが表示されるので、
    run [コマンドラインに与える引数]
を実行します。 下記は実行例です。
pegasus{hirano}[97]: gdb a.out
GNU gdb 4.18 (FreeBSD)
Copyright 1998 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-unknown-freebsd"...Deprecated bfd_read called at /usr/src/gnu/usr.bin/binutils/gdb/../../../../contrib/gdb/gdb/dbxread.c line 2627 in elfstab_build_psymtabs
Deprecated bfd_read called at /usr/src/gnu/usr.bin/binutils/gdb/../../../../contrib/gdb/gdb/dbxread.c line 933 in fill_symbuf

(gdb) run
Starting program: /tmp/a.out 

Program received signal SIGBUS, Bus error.
main () at test.c:5
5               x[10000] = 0;
(gdb) 

実行中のプログラムをデバッグする

 プログラムを実行し始めてから停止するまでの間にデバッガを介入させる方法です。 デバッグ対象のプログラムを実行して、 ps等でプロセスIDを調べてから、下記を実行します。

    gdb プログラム プロセスID
(gdb) というプロンプトが表示されて、 プログラムの実行は一時停止します。 continueコマンドで実行を再開します。 stepコマンドを用いて N行ずつ実行することもできます。


gdbの主なコマンド


もっと詳しく知りたい

  Debugging with GDB (日本語) あたりをどうぞ。


(作成: 2003年2月6日, 最終更新: 2003年6月27日)