とにかくちょっと使ってみる

gdbをとにかくちょっと使ってみた.
準備
gdbの起動から終了まで
別の実行方法
Shellコマンド
注意点

準備

gdbはどんな風に使用するのか,簡単な使用方法を通して示してみたい.まず以下のようなソースがあるとする.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
  int i;
  int loop_max;

  if(argc != 2){
    fprintf(stderr,"Usage %s loop-max\n",argv[0]);
    exit(EXIT_FAILURE);
  }

  loop_max = atoi(argv[1]);

  for(i = 0; i < loop_max; i++){
    fprintf(stdout,"i = %d\n",i);
  }

  exit(EXIT_SUCCESS);
}
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
  int i;
  int loop_max;

  if(argc != 2){
    fprintf(stderr,"Usage %s loop-max\n",argv[0]);
    exit(EXIT_FAILURE);
  }

  loop_max = atoi(argv[1]);

  for(i = 0; i < loop_max; i++){
    fprintf(stdout,"i = %d\n",i);
  }

  exit(EXIT_SUCCESS);
}

gdbの起動から終了まで

では,gdbを起動してみる.
$ gdb a.out
すると(gdb)というgdbのプロンプトが表示される.ここでrunとすると実行を開始する.
(gdb) run
Starting program: /home/hoge/programing/c/learn-gdb/intro/a.out 
Usage /home/hoge/programing/c/learn-gdb/intro/a.out loop-max

Program exited with code 01.
今回のサンプルでは起動時に引数を渡す必要があるので,runだけだとEXIT_FAILUREで終了した.こんどは引数を渡してみる.
(gdb) run 2
Starting program: /home/hoge/programing/c/learn-gdb/intro/a.out 2
i = 0
i = 1

Program exited normally.
こんどは引数で指定した回数分printfして正常終了した.ではgdbを終える.
(gdb) quit

別の実行方法

上ではgdbの起動時に実行ファイルを指定したが,他の方法もある.
$ gdb
(gdb) file a.out 
Reading symbols from a.out...done.
(gdb) run
Starting program: /home/hoge/programing/c/learn-gdb/intro/a.out 
Usage /home/hoge/programing/c/learn-gdb/intro/a.out loop-max

Program exited with code 01.
(gdb) quit
また,引数の渡し方もrunに直接渡すのではなく
set args
で指定することもできる.
$ gdb a.out 
(gdb) set args 2
(gdb) show args
Argument list to give program being debugged when it is started is "2".
(gdb) run
Starting program: /home/hoge/programing/c/learn-gdb/intro/a.out 2
i = 0
i = 1

Program exited normally.
(gdb) quit
上のように設定した引数は
show args
で確認できる.

Shellコマンド

gdbのプロンプトでShellコマンドを実行することができる.
(gdb) shell echo hoge
hoge
また,Shellモードになったりもできる.
(gdb) shell
$ exit
exit
(gdb)

注意点

runしたときにgdbの起動引数やfileコマンドで指定したファイルのタイムスタンプが変わっているとgdbはそのファイルを再読み込みする.このとき後述するbreakポイントなどは保持しようとする.
$ gcc intro.c
$ gdb a.out 
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-linux"...(no debugging symbols found)...
(gdb) break main
Breakpoint 1 at 0x80484b6
(gdb) run
Starting program: /home/hoge/programing/c/learn-gdb/intro/a.out 
(no debugging symbols found)...(no debugging symbols found)...
Breakpoint 1, 0x080484b6 in main ()
(gdb) cont
Continuing.
Usage /home/hoge/programing/c/learn-gdb/intro/a.out loop-max

Program exited with code 01.
(gdb) shell gcc -g intro.c 
(gdb) run
`/home/hoge/programing/c/learn-gdb/intro/a.out' has changed; re-reading symbols.
Breakpoint 1 at 0x80484b6: file intro.c, line 9.
Starting program: /home/hoge/programing/c/learn-gdb/intro/a.out 

Breakpoint 1, main (argc=1, argv=0xbffff704) at intro.c:9
9         if(argc != 2){
(gdb) cont
Continuing.
Usage /home/hoge/programing/c/learn-gdb/intro/a.out loop-max

Program exited with code 01.
(gdb) quit
上の例は,ストーリーとしてはgccしてgdbに書けてみたけど,シンボル情報がないと言われたので,もう一回コンパイルしてrunしたら実行ファイルがリロードされてbreakポイントはちゃんと保持されていたというものである.

This article was written by Fujiko