2012年11月10日土曜日

対話式デバッガ: GDB

バグを取る、つまりデバッグの手段として一番シンプルな方法は恐らく文を出力することだと思います。
怪しい変数の値を出力させたり、途中でプログラムが止まってしまう場合は怪しい処理の前後で文を出力させたりなど。

それ以外にも、 この記事この記事の方法を使うという手もあります。

実はそれ以外にも方法があるんです!
それは、デバッガを使うということ。
gccやg++にはGDBというデバッグツールが提供されています。
その使い方を今回はご紹介致します。


まず何かしらバグが起こってしまったプログラム"program"があるとします。
これを"-g"オプションを付けてコンパイルし直します。
gcc program.c -o program -g

ここからGDBの出番です。
ターミナルで以下のように入力します。
gdb ./program

これでGDBが起動します。

ここからは具体的な例とかを示しながら説明したいんですけど、面倒くさいんでGDBで使えるコマンドを列挙していきたいと思います。
  • run
    • GDB内でプログラムを実行する。
  • break <行番号か関数名>
    •  指定した行番号か関数の先頭にブレークポイントというものを挿入する。これにより、プログラムを実行してからブレークポイントに到達した時点で停止する。
  • step
    • プログラムの1行を実行するが、その文が関数呼び出しを含んでいる場合その関数に飛んでその中の1行が実行される。
  • next
    • プログラムの1行を実行するが、関数呼び出しも1行として扱われる。
  • cont
    • 停止しているプログラムを再開させる。
  • list
    • 行番号や関数名を指定して、そのソースコードを表示する。行番号をコンマ","で区切ると範囲を指定することもできる。
  • where
    • 現在実行中の関数のソースコードを表示する。
  • print <変数など>
    • 変数などの現在の値を表示する。
  •  status
    • 設定してあるブレークポイントを表示する。
  • delete <番号>
    • statusコマンドで見られる番号のブレークポイントを削除する。
基本的なのはこれくらいでしょうか。
helpコマンドで色々見れるらしいのでもっと極めたい人はどうぞご勝手に。

僕がよく使うやり方として、「プログラムが途中で止まってしまう場合」と「プログラムは最後まで通るけど結果がおかしい場合」の2パターンのバグに対してそれぞれ対処法があります。
前者の場合だと、まずrunで実行して、もちろん途中で止まるのでwhereでどこで止まったかを見ます。
そしてその場所以前にブレークポイントをいくつか挿入してnextとstepで実行していきながらprintで怪しい変数の値を見るといった感じです。
Segmentation faultが出たときとかこれが有効です。

後者の場合は、適当にブレークポイントを設定してprintで値を見ていく感じですが、何度もプログラムを実行してmain関数内のどの辺でバグが起こっているかを突きとめてから徐々に細かい呼び出し関数内まで見ていくというやり方です。

何か酔っぱらってきたのでこの辺で失礼。

0 件のコメント :

コメントを投稿