gdbの利用例(その1)

gdbを使って,サンプル[*]sample/c/sample1.cにおける strtokの動作を確認してみよう. 次のように-gオプションをつけてgccでコンパイルすれば,gdb上でこのプログラムをデバッグすることができる.
   % gcc -g -o sample1 sample1.c
   % gdb sample1
   ... gdbのメッセージ ...
   (gdb)
最後の(gdb)コマンドを待つプロンプトである. ここで,runコマンドを実行すると,通常通りプログラムの実行が開始され る.プログラムにコマンドライン引数を渡す場合は,このrunに引数を与 えればよい.
   (gdb) run
   Starting program: .../sample1
   foo, bar, hoge       (foo, bar, hoge を入力)

   1 = foo; 2nd = bar; 3 = hoge
   [Inferior 1 (process XXXXX) exited normally]

次に,プログラム実行途中での変数の値を表示させて,strtokの動作を確 認してみよう. プログラムを最初のstrtokの手前で一時停止させるために,ブレーク・ポ イントを利用することができる.

   (gdb) break 9
と,breakコマンドによってブレーク・ポイントを9行目(a = strtok(...)の 行)に設定する.この状態でrunコマンドを実行し,入力文字列として, 上と同様にfoo, bar, hogeを与えると,strtokは実行されずに
   Breakpoint 1, main () at sample1.c:9
   9   a = strtok(in, " ,\n");
と表示されて,実行が一時停止される.このメッセージは,sample1.c の9行目(の先頭)で停止していることを示している.ここで,printコマ ンドを利用して,式in[0](つまり,文字列inの1文字目)を表示させ ると,
   (gdb) print in[0]
   $1 = 102 'f'
in[0]の内容が正しく102(文字としてはf)になっていることが確認 できる.単にprint inとすると,
   (gdb) print in
   $2 = "foo, bar, hoge\n\000\005..."
と,終端文字より先も含めて,配列としてのinの値が全て表示される.こ れによって,改行文字 \ nの次が終端文字' \ 000'になっていることがわかる.また,printfを利用して フォーマットを指定して表示することもできるし,whatを利用して式の型 を確認することもできる.
   (gdb) printf "%s\n",in
   foo, bar, hoge
   (gdb) what in
   type = char [40]
ここでstepコマンドを実行すると,「次の命令のみ」を実行することがで きる(ステップ・イン実行).
   (gdb) step
   10   b = strtok(NULL, " ,\n");
この時点でのaの内容と,inの内容を調べてみよう.
   (gdb) printf "%s\n",a
   foo
   (gdb) print in
   $3 = "foo\000 bar, hoge\n\000\005..."
aの内容が確かに最初のトークンfooになっていることがわかる.ま た,もとの文字列in中の最初の区切り文字だった4文字目のカンマが終端文 字' \ 000'に置き換えられていることもわかる.同様に,
   (gdb) step
   11   c = strtok(NULL, " ,\n");
   (gdb) printf "%s\n",b
   bar
   (gdb) print in
   $4 = "foo\000 bar\000 hoge\n\000\005..."
と,2回目のstrtokによって,2つめのトークンbarbに格納 され,barの後の区切り文字だったカンマが終端文字' \ 000'に置き換えられていることがわかる. 以上のように,strtok関数は,区切り文字を終端文字に置き換えながら, 返り値としてトークン文字列を返していることがわかる.

ブレーク・ポイント以降の実行を続 けるには,continueコマンドを実行する.

   (gdb) continue
   Continuing.
   1st = foo; 2nd = bar; 3rd = hoge
   [Inferior 1 (process XXXXX) exited normally]
ブレーク・ポイントは複数設定することが可能であり,この場合continue コマンドによって「次のブレーク・ポイント」までが実行される.現在設定中の ブレーク・ポイントは
   (gdb) info breakpoints
で一覧表示できる.また,設定したブレーク・ポイントは,
   (gdb) delete 1
などで削除できる.引数は行番号ではなく,ブレーク・ポイントの通し番号(info breakpointsで確認できる)であることに注意.

gdbを終了する場合は,quitコマンドを実行する.

NAKAZAWA Koji
2014-09-30