ふつうのLinuxプログラミング 第7章 gdb

以前にも使ったことのあるgdb。以前に使ったときはアセンブラデバッグだったので、あまり有用性を感じなかった。

今回はcのデバッグに使ったのが、かなり有効に使えることがわかった。メモっておく。

% gcc -Wall -g -o head head.c
% gdb head
(gdb) r -n 5
Starting program: /home/tanaka/study/c/normal/head/head -n 5

Program received signal SIGSEGV, Segmentation fault.
0x0095c07b in ____strtol_l_internal () from /lib/libc.so.6
(gdb) bt
#3  0x0804860b in main (argc=3, argv=0xbf941744) at head.c:27
(gdb) f 3
#3  0x0804860b in main (argc=3, argv=0xbf941744) at head.c:27
27                                      lines = atoi(optarg);
(gdb) l
26                              case 'n':
27                                      lines = atoi(optarg);
28                                      break;
(gdb) p opt
opt                opterr             optind@@GLIBC_2.0  optopt
optarg             optimize_subexps   option
optarg@@GLIBC_2.0  optind             option_alloc
(gdb) p optarg
$1 = 0x0
(gdb) p opt
$2 = 110
(gdb) c
(gdb) q

まとめると

r [引数]
実行
bt
バックトレースを見る。
f [n]
フレーム nに移動
l
リストを見る
p
変数表示
c
続ける
q
終わり

どうやら変数の補完も効くようなのでprintするより便利かもしれない。

ブレークポイントの仕掛け方も復習しておこう・・・

ブレークポイントの仕掛け方は、

(gdb) b main
Breakpoint 1, main (argc=3, argv=0xbfe4dc54) at head.c:22
22              int lines = DEFAULT_LINES;
(gdb) s
23              while ((opt = getopt_long(argc, argv, "nh", longopts, NULL)) != -1) {
(gdb) s
24                                      printf("hello getopt_long %c\n", opt);
...

おぉぉぉぉぉ。便利杉。

まとめると、

b [関数名]
関数にブレークポイントを仕掛ける
s
ステップ実行

その他に、

watch [変数名]
変数が変わったときにブレークポイント

printfより便利ですねぇ・・・。いちいちgdbを立ち上げるのが面倒なので、printfとどっちが早いかは微妙。

でも、絶対覚えるべし・・・やること増えるなぁ・・・とほほ。

gcc+gdbによるプログラムのデバッグ
おぉ。チュートリアル発見。