最近毎日毎日C++を書いてはデバッグ作業に追われているわけですが、やはりいつまでもcerrやprintfで対応しているわけにもいかないのでそろそろgdbの使い方でも覚えようかと思い立ち、使ってみました。
…やべえこれ便利すぎる。なんで今まで使わなかったんだろう。というわけで、今日一日使ってみて特に使ったコマンドなんかを順を追って列挙してみます。
- まずはコンパイルする
# gcc -g -O2 main.cpp -o main
デバッグオプションは-gで、最適化オプションはO2くらいがいいかと。ちなみにgccのバージョンは3.4.4です。
- デバッグするバイナリを呼び出す。
# gdb hoge (gdb) set args [options]
ここでset argsで起動オプション指定してますが,別にrunするときにつけても大丈夫です.何度も同じオプションでrunするときはset argsの方が楽ですね.
- ブレイクポイントを打つ
(gdb) break LINENUM (gdb) break FILENAME:LINENUM (gdb) break FILENAME:FUNCNAME
LINENUMは行番号。コメントとか空白行も含めての行番号。FUNCNAMEは関数名。複数ファイルでビルドしているときなんかはよく ファイル名:行番号 でブレイクポイント打ってます。
- ブレイクポイントを確認して、いらないやつは消す
(gdb) info breakpoint Num Type Disp Enb Address What 1 breakpoint keep y 0x08048a10 in main at hoge.c:45 2 breakpoint keep y 0x07093a10 in main at hoge.c:60 (gdb) delete NUM
NUMはブレイクポイントの情報にあるインデックスの番号。
- いざ実行。そしてステップ実行。あるいはブレークポイント間実行
(gdb) run (gdb) next [count] (gdb) step [count] (gdb) until (gdb) finish (gdb) continue [count]
nextとstepはほぼ同じ挙動。関数に入ったときの挙動が違うだけ。countの数だけ繰り返し進みます。untilもstepとかと同じだけど、ループに入ったときに2回目以降の繰り返しをスキップ。finishは今いる関数の最後まで実行。continueは次のブレイクポイントまで実行。
- 気になる変数を表示
(gdb) print foo
fooの中身を表示します。これがめちゃ便利。今までcerrで表示してたのが残念。
なおたいていのコマンドが省略形を持っていて、そのコマンドの最初のアルファベットになってます。例えばprintならpみたいな。