YAMAGUCHI::weblog

噛み付き地蔵に憧れて、この神の世界にやってきました。マドンナみたいな男の子、コッペです。

GDBを使う(はじめて編)

最近毎日毎日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みたいな。