Section Next | Prev


2.5 シンボリック・デバッガー

シンボリック・デバッガ(gdb) は、プログラムを実行しながら変数の内容を 表示、変更したり、適当な個所で実行を中断させたりするツールです。
gdb を利用するには、事前にデバッグオプション(-g) によって、コンパイル されていなければなりません。
	$ gcc -g prog.c -o prog
gdb を起動するときには、 引き数に実行プログラム名を指定します。
	$ gdb prog
gdb が起動されるとプロンプトが (gdb) に変わり、 gdb のサブコマンド入力待ちとなります。
また予め特定のサブコマンド群を起動時に実行させたい場合には、初期設定ファイル .gdbinit にコマンド列を記述します。
.gdbinit がカレントディレクトリにない場合はホームディレクトリの .gdbinit が採用されます。
gdb を終了する場合は quit サブコマンドによります。
	(gdb) quit
gdb の主なサブコマンド
文法意味
stop in 関数名 ブレークポイント(中断点)を設定する。
stop at 行 同上
run, rerun プログラムの実行(指定したブレークポイントまで実行する)
cont ブレークポイントで中断したプログラムの実行再開
print 変数の内容表示
step, next 1行づつ実行する。
delete 既存のブレークポイントの解除
status 既存のブレークポイントの表示
trace 変数の内容が変わった場合や、指定した行を通過した時にその旨を表示

2.5.1 プログラムの起動

【機能説明】
run サブコマンドは現在操作中のプログラムを最初から実行します。 出力結果をリダイレクションして別ファイルに保存する事も出来ます。

【入力フォーマット】
run [ 引数 ] [ < ファイル名 ] [ > ファイル名 ]

【実行例】
プログラムの実行
	$ cat -n bbb.c
	    1 red()
	    2 {
	    3     printf("This is RED\\n");
	    4 }
	    5 blue()
	    6 {
	    7     printf("This is BLUE\\n");
	    8 }
	    9 main()
	   10 {
	   11     red();
	   12     blue();
	   13     printf("The END\\n");
	   14 }

	$ cc bbb.c -g
	$ gdb a.out
	GNU gdb Red Hat Linux (6.3.0.0-1.143.el4rh)
	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-redhat-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1".

	(gdb) run
	Starting program: /home/ycos/bin2/a.out
	This is RED

	This is BLUE

	The END


	Program exited with code 011.
	(gdb) quit

2.5.2 特定の変数・行・サブルーチンの追跡

【機能説明】
trace サブコマンドは指定した条件に従って、実行した行や変数内容を表示します。
【入力フォーマット】
  • trace [ if 条件式 ]
    条件式が真のとき、実行するすべての行を表示します。
  • trace at 行番号 [ if 条件式 ]
    条件式が真のとき、指定した行番号を実行するときにその行を表示します。
  • trace in サブルーチン名 [ if 条件式 ]
    条件式が真のとき、指定した関数を呼び出す時にその行を表示します。
  • trace 式 at 行番号 [ if 条件式 ]
    条件式が真のとき、指定した行番号に達したときに指定した式の値を表示します。
  • trace 変数名 [ if 条件式 ]
    条件式が真のとき、指定した変数に変化があった時にその変数の値を表示します。

条件式は論理式で、 if 条件式 の項が付いているときは条件式が真のときに限り実行されます。

【実行例】
変数 i が 5 よりも大きい時にその値を表示する
	% cat -n ccc.c
	 1 func( x )
	 2 int x;
	 3 {
	 4 	if( x < 8 )
	 5 		printf("Data %d, Oct:%02o, Hex:%02X\\n", x, x, x);
	 6 	else
	 7 		printf("Data %d, Oct:%o, Hex:%X\\n", x, x, x);
	 8 }
	 9 main()
	10 {
	11 	int i;
	12 	for(i=0;i≶10;i++\func(i);) h
	13 }
	% cc ccc.c -g -o ccc
	% gdb ccc
	gdb version 3.0.1
	Type 'help' for help.
	main:  12  for(i=0;i<10;i++\func(i);) h
	(gdb) trace i at 4 if i > 5
	[2] if i > 5 { i }  at "ccc.c":4
	(gdb) run
	Data 0, Oct:00, Hex:00
	Data 1, Oct:01, Hex:01
	Data 2, Oct:02, Hex:02
	Data 3, Oct:03, Hex:03
	Data 4, Oct:04, Hex:04
	Data 5, Oct:05, Hex:05
	[2] [func:4 ,0x400b6c]: i = 6
	Data 6, Oct:06, Hex:06
	[2] [func:4 ,0x400b6c]: i = 7
	Data 7, Oct:07, Hex:07
	[2] [func:4 ,0x400b6c]: i = 8
	Data 8, Oct:10, Hex:8
	[2] [func:4 ,0x400b6c]: i = 9
	Data 9, Oct:11, Hex:9
	Program terminated normally

2.5.3 ブレークポイントの設定

【機能説明】
サブコマンド stop は、指定した場所で実行を止めることができます。

【入力フォーマット】
  1. stop if 条件式
    条件式が真のとき、実行を中断する。
  2. stop at 行番号 [ if 条件式 ]
    指定された行番号に制御が移ったとき、条件が真なら実行を中断。
  3. stop in サブルーチン名 [ if 条件式 ]
    指定された関数に制御が移ったとき、条件が真なら実行を中断。
  4. stop 変数名 [ if 条件式 ]
    指定された変数に変化があったとき、条件が真なら実行を中断。
条件式は論理式で、 if 条件式 の項が付いているときは 条件式が真のときに限り実行されます。 数の値が変わったときに止まります。
【実行例】
	% gdb ccc
	gdb version 3.0.1
	Type 'help' for help.
	main:  12  for(i=0;i<10;i++\func(i);) h
	(gdb) stop in func
	[2] stop in func
	(gdb) run
	[2] stopped at
	[func:4 ,0x400b6c]
	if( x < 8 )
	(gdb) quit

2.5.4 トレース/ブレークポイントの表示と解除

【機能説明】
status サブコマンドは trace と stop の設定状況を表示します。 これらの設定を解除するには delete を用います。

【入力フォーマット】
	status
	delete コマンド番号
【実行例】
status,delete 実行例
	% cat -n hello.c
	    1 main()
	    2 {
	    3     char buff[80];
	    4
	    5     printf("Your name please: ");
	    6     scanf("%s",buff);
	    7     printf("\\nThank you %s-san\\n",buff);
	    8     puts("How are you?\\n");
	    9 }
	% cc hello.c -g
	% gdb a.out
	gdb version 3.0.1
	Type 'help' for help.
	main:
	5 printf("Your name please: ");
	(gdb) stop at 6
	[2] stop at "hello.c":6
	(gdb) run
	[2] stopped at
	[main:6 ,0x400bc8]
	scanf("%s",buff);
	(gdb) status
	[2] stop at "hello.c":6
	(gdb) delete 2
	(gdb) run
	Your name please: 
	Ycos
	Thank you Ycos-san
	How are you?
	Program terminated normally
	(gdb) quit

2.5.5 ステップ実行

【機能説明】
1行づつ動作を確認しながら実行するにはサブコマンド next,cont,step を用います。 step, next とも1行づつ実行しますが、next は途中で関数がよばれても、その 内部へはゆかず、関数から制御が戻ってくるまで処理を行います。next は関数へ 制御が移っても、1行づつ実行してゆきます。
cont はつぎのブレークポイントまで実行を再開します。
【入力フォーマット】
	cont
	step
	next
【実行例】
ブレークポイントをソースの3行目に設定し、実行した場合。
	% gdb a.out
	gdb version 3.0.1
	Type 'help' for help.
	main: 11 red();
	(gdb) stop at 3
	[2] stop at "bbb.c":3
	(gdb) run
	[2] stopped at
	[red:3 ,0x400b88]
	printf("This is RED\\n");
	(gdb) next
	This is RED [red:4 ,0x400ba8]
	(gdb) cont
	This is BLUE
	The END
	Program terminated normally
1行づつ実行する場合 ( step を使って)
	% gdb a.out
	gdb version 3.0.1
	Type 'help' for help.
	main:  11  red();
	(gdb) stop at 3
	[2] stop at "bbb.c":3
	(gdb) run
	[2] stopped at
	[red:3 ,0x400b88]
	printf("This is RED\\n");
	(gdb) step
	This is RED
	[red:4 ,0x400ba8]
	(gdb) step
	[main:12 ,0x400c30]
	blue();
	(gdb) step
	[blue:7 ,0x400bd8]
	printf("This is BLUE\\n");
	(gdb) step
	This is BLUE
	[blue:8 ,0x400bf8]
	(gdb) step
	[main:13 ,0x400c38]
	printf("The END\\n");
	(gdb) step
	The END
	[main:14 ,0x400c58]
1行づつ実行する場合 ( next を使って)
	% gdb a.out
	gdb version 3.0.1
	Type 'help' for help.
	main:  11  red();
	(gdb) stop at 3
	[2] stop at "bbb.c":3
	(gdb) run
	[2] stopped at
	[red:3 ,0x400b88]
	printf("This is RED\\n");
	(gdb) next
	This is RED
	[red:4 ,0x400ba8]
	(gdb) next
	[main:12 ,0x400c30]
	blue();
	(gdb) next
	This is BLUE
	[main:13 ,0x400c38]
	printf("The END\\n");
	(gdb) next
	The END
	[main:14 ,0x400c58]
	(gdb) next
	[__start:196 ,0x400ad8]
	Source not available

2.5.6 式の値の表示

(print, printf, dump)
【機能説明】
print, printf サブコマンドは簡単な計算結果を表示したり、変数の値を表示します。
このとき表記方法に若干の制限があります。
  • 配列 arry[]
    配列を表すときはいつでも ( FORTRAN でも) 大かっこ [] を用いる

  • ポインタ参照
    C のポインタ変数が示す先の内容を得るには、変数名の最初にアスタリスク(*)
  • を付ける。

print サブコマンドは、 単純に変数の値を表示します。予め alias により (後述) p と略記できます。
printf サブコマンドは、書式を変更して、変数の値を表示します。書式は C言語 の printf(3) に準拠しています。
dump は現在使われている全変数とその値を表示します。
【入力フォーマット】
	print   式 [ , 式… ]
	printf "書式", 式 [, 式…]
	dump
また print 系のサブコマンドは頻繁に用いられるため、予め以下の alias が定義されています。
Alias 定義内容 意味
px printf "0x%x\\n", 16進数で、変数/定数を表示
po printf "0%o\\n", 8進数で、変数/定数を表示
pd printf "%d\\n", 10進数で、変数/定数を表示
p print 書式編集なしの表示
pr printregs レジスタの内容一覧
【実行例】
	% cat -n ddd.c
	1 main()
	2 {
	3     int i;
	4     char *text="This is SAMPLE.";
	5     for(i=0;i<strlen(text);i++){
	6         printf("%c\\n",text[i]);
	7     }
	8 }
	% cc -g ddd.c -o ddd
	% gdb ddd
	gdb version 3.11.10
	Type 'help' for help.

	main:   4  char *text="This is SAMPLE.";
	(gdb) stop in 6 # 実は in と at を間違っても文脈から正しく解釈してくれる
	[2] stop at "a.c":6
	(gdb) run
	[2] stopped at   [main:6 ,0x120001334]  printf("%c\\n",text[i]);
	(gdb) next
	  [main:7 ,0x120001370]         }
	(gdb) next
	  [main:5 +0x4,0x120001314]     for(i=0;inext
	  [main:6 ,0x120001334]         printf("%c\\n",text[i]);
	(gdb) print text[i]
	'h'
	(gdb) p i
	1
	(gdb) p *text
	'T'
	(gdb) p text
	0x140000010 = "This is SAMPLE."
	(gdb) quit

2.5.7 変数への値代入

【機能説明】
assin はデッバッグ中のプログラムの変数に値を設定します。
set は gdb の動作を制御している gdb 変数に値を設定します。
assign, set とも使いかたは全く同じで、指定した変数に指定された式の値 をセットします。
引き数なしの set はデバッガ値数の一覧を表示します。
【入力フォーマット】
	assign 変数式 = 式
	set [$変数名 = 式 ]
【実行例】
gdb 変数 $page はトレース情報などが画面に収まりきれない場合に、一時中断 するかどうかを設定します。
	(gdb) set $page=1	(gdb)set $page=0
	(gdb) set		(gdb)set
	$rld_root       ""		$rld_root	""
	$job_control    1		$job_control    1
	$newevent       3		$newevent       3
		:				:
	$printwhilestep 0		$cursource      "pz_kdtree.c"
	$printwide      0		$curpc          4834306948
	More (n if no)?			   < 最後までとまらない >
プログラムをいったん中断し、変数 (i) の値を変更した後、実行を再開する。 デバッガの変数の表示と変更
	4  char *text="This is SAMPLE.";
	(gdb) stop in 6
	[2] stop at 6
	(gdb) run
	[2] stopped at [main:6 ,0x400be8] printf("%c\\n",text[i]);
	(gdb) next
	T
	[main:6 ,0x400be8] printf("%c\\n",text[i]);
	(gdb) next
	h
	[main:6 ,0x400be8] printf("%c\\n",text[i]);
	(gdb) p i
	2
	(gdb) assign i=8
	8
	(gdb) next
	S
	[main:6 ,0x400be8] printf("%c\\n",text[i]);
	(gdb) next
	A
	[main:6 ,0x400be8] printf("%c\\n",text[i]);
	(gdb) set
	$stop_on_fork   1
	$stop_on_exec   1
		: 中略
	$regstyle       1
	$readtextfile   1
	More (n if no)?n
	(gdb) set $prompt="DEBUG> "
	DEBUG> quit

2.5.8 停止状態の表示

【機能説明】
where は停止した状態を表示します。これは特に core を伴って gdb を起動し、 異常終了したプログラムの原因追及に有効です。
【入力フォーマット】
where
【実行例】
プログラムが異常終了した後、異常箇所を特定する。
	% cat -n a.c
	    1 #include 
	    2 #include 
	    3 #define MSG "Hello!\\n"
	    4
	    5 main()
	    6 {
	    7 FILE *log;
	    8
	    9 log=fopen("/log","w+");
	    10 write(fileno(log), MSG, sizeof MSG );
	    11 fclose(log);
	    12 }
	% a.out
	Memory fault(コアダンプ)
	% gdb a.out core
	gdb version 3.11.10
	Type 'help' for help.
	Core file created by program "b"

	signal Segmentation fault at   [main:10 +0x4,0x120001344]       write(fileno(log
	), MSG, sizeof MSG );
	(gdb) where
	>  0 main() ["b.c":10, 0x120001344]
	(gdb) dump
	main() ["b.c":10, 0x120001344]
	log = (nil)
	(gdb) quit

2.5.9 ソースプログラムの表示(list)

【機能説明】
list は現在のソースファイルを表示します。
特に指定しない限り、デバッガ変数 $listdwindow(省略値は12) で定義された行数を表示します。

【入力フォーマット】
  1. list
    カレント行から 12 行($listwindow分)を表示
  2. list line
    line 指定 された行から表示
  3. list line, n
    指定 された行 ( line ) から n 行表示
  4. list func
    指定した関数 ( func) から表示
現在実行中のプログラムが、起動時(デフォルト)とは違うソース・ファイルの場合は file または func コマンドにより、ソース・ファイルを明示することができます。 またソース・ファイルのあるディレクトリが、実行ディレクトリと異なる場合は use コマンドによりディレクトリを変更します。

【実行例】
先頭からソースプログラムを表示し、デバッガ変数 $listwindow を変更後、 再度ソースを表示。
(gdb) list 1
    1 #include 
    2
    3 #define SEG_MAX 5
    4
         : 中略
   11 XGCValues gcvalue;
   12 int i,x, y, width, height;
(gdb) set $listwindow=20
(gdb) list 1
    1 #include 
    2
    3 #define SEG_MAX 5
    4
             : 中略
   17 x = y = 0;
   18 width = XDisplayWidth (display, 0);
   19 height = XDisplayHeight (display, 0);
   20 window = XCreateSimpleWindow (display, 

2.5.10 コマンドの別名定義 (alias)

【機能説明】
コマンド alias は、コマンドを組み合わせて新しいコマンドを定義したり、省略した コマンドを定義します。
引き数なしの alias は現在定義されている内容を表示します。

定義されている alias を解除するには unalias コマンドを用います。

【入力フォーマット】
	alias   [ 別名 コマンド列 ]
	unalias 別名
【実行例】
next と変数の表示を合わせて、 A というコマンドに定義する。
	(gdb) next	以下の行は i についてループしている物とする
	[main:6 ,0x400be8]    printf("%c\\n",text[i]);
	(gdb) print i
	0
	(gdb) alias A "next;print i"
	(gdb) A
	[main:6 ,0x400be8]    printf("%c\\n",text[i]);
	1
	(gdb) A
	[main:6 ,0x400be8]    printf("%c\\n",text[i]);
	2
	(gdb) alias
	A       next;print i
	source  playback input
	Si      nexti
		  : 
		中略
	pi      playback input
	pd      printf "%d\\n",
	More (n if no)? n
	(gdb) unalias A
	(gdb) alias
	source  playback input
	Si      nexti
	S       next
		:
		中略
	pi      playback input
	pd      printf "%d\\n",
	p       print
	More (n if no)? n

2.5.11 その他のコマンド

  • source - gdb コマンド・ファイルの実行
    【機能説明】
    source コマンドは gdb のコマンドの書かれたファイルを読みこみ実行します。

    【入力フォーマット】
    source コマンドファイル名

    なお、.gdbinit ファイルは gdb 起動時に実行される特別なコマンドファイル です。

    【実行例】
    	% cat .gdbinit
    	stop in main
    	list 1
    	% gdb gt_scan
    	gdb version 3.11.10
    	Type 'help' for help.
    
    	[2] stop in main
    	     1 main( int argc, char* argv[] )
    	     2 {
    	     3     int a, b, c;
    			: 
    
  • sh - シェル・コマンドの実行
    【機能説明】
    コマンド sh は、シェルコマンドを実行します。 このとき使用されるシェルプログラムは 環境変数 SHELL で指定されている物が採用されます。

    【入力フォーマット】
    sh コマンド列

    【実行例】
    	(gdb) sh date
    	1997年12月05日 12時11分47秒
    	(gdb) sh grep main */*.c | wc -l
    		 2
    
  • use - ソース・ファイル検索ディレクトリの指定
    【機能説明】
    通常 gdb は、実行時のカレント・ディレクトリおよび指定した実行イメージがある ディレクトリに、ソースファイルがあると仮定します。 したがって、これらの場所にソースファイルがない場合は use コマンドにより、 ソースのありかを指定します。

    【入力フォーマット】
    use ディレクトリ名…

    【実行例】
    ソースファイルが見付からない時はエラー表示がある
    	main:    Source not available
    	(gdb) use gt9000
    	(gdb) list
    	    24  /* options check */
    	    25
    
  • help - ヘルプ表示
    【機能説明】
    help は gdb の各サブコマンドの概要、及び簡単な使い方を表示します。

    【入力フォーマット】
    help [キーワード]

A. gdb の主なコマンド

gdb のコマンドについて、以下にその概要をまとめます。
コマンド書式意味
run プログラムの実行を開始。
cont 中断したプログラムの実行を再開する。
step 1行実行して止まる(関数の中に入る)。
quit gdb の終了
next 1行実行して止まる(関数を飛ばす)。
trace line 指定した行 (line) を実行するたび、それを表示。
trace proc 指定した関数 ( proc ) を実行するたび、それを表示。
trace var 指定した変数の値 ( var) が変わったときそれを表示する。
stop at line 指定した行番号 ( line) で止まる。
stop in proc 指定した関数 ( proc ) に入るとき止まる。
status 設定されているブレークポイント(停止条件)や表示状態を表示する。
delete number 指定された番号 ( number) のブレークポイント、 trace を取り除く。
call proc 指定したサブルーチン ( proc) を実行する。
where 現在実行中の場所(関数名、ソースファイル名、行数)を表示する。
print exp 指定した式 ( exp) の値を表示する。
whatis name 指定した変数 ( name) の型宣言を表示する。
list line [: width ] ソース・プログラムの line から width 行を表示。
edit proc 指定した関数 ( proc) を含むファイルを編集する。
sh [commands] シェルコマンドを使用する。
引き数なしの場合はシェルの対話モードになり、^D(or exit) で gdb に戻る。

Section Next | Prev

Copyright ycosSystems 2007, prgBasic/Body25.html