GDB メモ

これだけ知っていれば、一仕事できます(実話)。

基本コマンド

bt
backtrace バックトレース
i r
info registers レジスタ
b
breakpoint ブレークポイント設置
d bre 1
delete breakpoint 1 ブレークポイント1を削除
c
continue ブレークポイントから復帰
fin
finish 今の関数を抜ける所まで実行
ni
next instruction 命令をステップ実行

アセンブル

通常は disassemble コマンドを使えば、指定した関数を逆アセンブルできる。引数なしだと、今いる関数が対象となる。strip されているバイナリを disassemble しようとすると、"No function contains specified address" と言われるので、$rip 周辺を

x/100i $rip

のようにすればよい。130(%eip) のようなアドレス指定は解決してくれる。

メモリ読み出しウォッチポイント

rwatch で、読み出しも監視できる。

x86_64 呼び出し規約(重要)

x86 だとスタックに積んでいくけど、x86_64 はレジスタが増えたのでなるべくレジスタを使うようになっている。引数を rdi, rsi, rdx, rcx, r8, r9 の順にレジスタに積んで call で呼び出し。返り値は rax。

x86/x86_64関数呼び出しチートシートを書いた | d.sunnyone.org で提供されているPDFがとても分かりやすい。

例: 文字列定数を調べる

例えば、sscanf の第2引数はフォーマット文字列へのポインタなので、これを調べたかったら sscanf にブレークポイントを仕掛けて、入ってすぐに

x/s $rsi

とすればよい。
x は間接参照。指定したアドレスの中身を書式に従って表示する。p は指定した引数の中身を書式に従って表示する。

メモリを検索

find コマンドを使う。検索範囲は、info variables とかやってヒープを探せばいい。定数を探すには、maintenance info sections などとする。

なお、Mac OS X の Developer Tools に入っている gdb は古いので、このコマンドが使えない。http://wiki.lazarus.freepascal.org/GDB_on_OS_X_Mavericks_and_Xcode_5 を参考にアップデートする。また、Universal Binary の場合は、ターゲット・アーキテクチャ用の部分だけを抽出する必要がある。http://stackoverflow.com/questions/20553784/gdb-on-mac-10-9-fails-with-not-in-executable-format-file-format-not-recognized 参照。