Hatena::ブログ(Diary)

しばそんノート

2009-06-24

GDBデバッギング覚え書き

使い方をよく忘れるので…。

リファレンス的なものではなく、要点のみの覚え書きです。

以下の記述は

  • gcc 4.1.2
  • gdb 6.8

を前提としています。

コンパイル

  • "-g"オプションは必須
  • "-O"系オプション(最適化)は付けない*1
  • stripしちゃダメ

プログラムの実行

$ gdb (progoram)

で起動して

(gdb) run

プログラムに引数を与えることもできます。また、標準入力、標準出力もリダイレクトで指定できます。

(gdb) run (arguments) < (input file) > (output file)

以下のコマンドで環境変数も設定できるので、この辺を組み合わせればCGIのデバッグも可能です。

(gdb) set env LANG=C

環境変数の確認は以下の通り。

(gdb) show env

CGIのデバッグをする場合はこんな感じになるのかな?

(gdb) set env PATH_INFO=/path/info
(gdb) set env QUERY_STRING=param1=value1&param2=value2
 …(略)…
(gdb) run < (POSTデータを記述したファイル)

2回目以降のrun時に明示的に引数を指定しない場合、前回の引数がそのまま使用されます。

現在設定されている引数を確認するのは

(gdb) show args

以下のように引数だけ先に指定しておくこともできます。

(gdb) set args foo bar baz

ブレイクポイント

関数の入り口に設定する場合は

(gdb) break hoge_function

ソース中の指定した行に設定する場合は

(gdb) break 30
(gdb) break hoge.c:60

条件付で設定する場合は

(gdb) break 100 if counter == 3
(gdb) break 200 if strlen(string) < 32

現在のブレイクポイント一覧を得るには

(gdb) info break

ブレイクポイントを指定した回数以上通過するまで無効化、という条件の指定もできます。ループの中にブレイクポイントを置く際なんかに重宝します。

(gdb) ignore 3 30

上の例では3番のブレイクポイントに対して、はじめの30回は無視するように指示しています。

ブレイクポイントの削除は次の通り。

(gdb) delete 5

全てのブレイクポイントを消したい場合は次のようにします。

(gdb) delete

フレームの表示と移動

現在どのフレームにいるかを知るには

(gdb) where

指定したフレームに移動するには

(gdb) frame 3

一つ上のフレームに移動するには

(gdb) up

一つ下のフレームに移動するには

(gdb) down

ソースの表示

単に

(gdb) list

と打つと、ブレイクポイントで停止した直後の場合はその前後の行が10行ほど、そうでない場合は最後に表示した行の次の行から10行表示されます。

行数や関数名を指定すると、その行を中心に前後10行表示されます。

(gdb) list 100
(gdb) list sample_function

開始行と終了行を指定することもできます。

(gdb) list 200,230

ステップ実行

1行処理を進めます。次の行が関数呼び出しの場合、その関数の中に入って停止します。引数を渡すと、その行数分進みます。

(gdb) step
(gdb) s
(gdb) s 10

1行処理を進めます。次の行が関数呼び出しの場合でも、「その行の処理が完了してから」停止します。つまり関数の中に入りません。引数を渡すと、その行数分進みます。

(gdb) next
(gdb) n
(gdb) n 10

次のブレイクポイント、もしくはプログラムの終了まで処理を続行します。

(gdb) continue
(gdb) c

変数の表示

ある変数の値を知りたい場合は以下のようにします。

(gdb) print param
(gdb) p param

現在のフレームから参照できるローカル変数の一覧は以下のように取得します。

(gdb) info locals

現在のフレームの引数の一覧も取得できます。

(gdb) info args

変数の値を変えてしまうこともできます。

(gdb) set var param = "Hello world!"

変数の自動表示

ある変数の値を、ブレイクポイントで停止する度に自動で表示させることができます。ループ中の値の変遷をチェックする場合などに便利です。

(gdb) display hoge

自動表示中の変数の一覧は

(gdb) display

自動表示を取りやめるには

(gdb) undisplay hoge

全ての自動表示を取りやめるには

(gdb) undisplay

変数の監視

あるいはもっと踏み込んで、ある変数の値が変更されたときに自動で停止させることもできます。「いつどこで変数が書き換えられたのかわからない」といった場合に便利です。

(gdb) watch moge

監視中の変数の一覧は

(gdb) info watch

これはブレイクポイントの一覧と同じ結果が出力されます。つまり、「ある変数が変更されたとき」という条件が設定されたブレイクポイントの一種なわけです。

そのため、削除などの操作は基本的にブレイクポイントのそれに準じます。

(gdb) delete 3

以下、そのうち追記…しないかも?

とりあえず困ったときは

ヘルプを見ればなんとかなります。

(gdb) help

参考

*1:付けてもデバッグできるけど、付けない方がなにかと面倒なことがないので望ましい

*2:ちょっとバージョンが古いですが、基本的な使い方の範囲では問題ないと思います