GDB


起動

gdb a.out
gdb -tui a.out        テキストユーザーインターフェイスで起動(GUIとはちょっと違う)
gdb a.out $pid        $PIDのプロセスにアタッチ起動
gdb a.out core        coreファイルを指定して解析
gdb -tui -x comfile a.out    comfileというファイルを読み込み起動時に実行

### comfileサンプル ############
b main                         #
disp /i $pc                    #
disp /x $eax                   #
disp /x $ebx                   #
################################

操作

r                    実行
bt                   スタックフレームの表示
c                    実行再会
s                    ステップ実行(C言語ソースレベル)
si                   ステップ実行(アセンブラーレベル)
n                    ネクスト実行(呼び出す関数の中に入らない。C言語ソースレベル)
ni                   ネクスト実行(呼び出す関数の中に入らない。アセンブラーレベル)
finish               リターンするまで実行
return exp           式expを戻り値に呼び出されている関数の実行をキャンセル
until                次の行まで実行する(ループの最終行から実行するとループ脱出)
until 10             10行目まで実行
advance main.c:funcA funcAまで実行。untilと違い関数の再帰をスキップせずカレントフレーム以外もOK
list                 ソースの表示
j main               main関数へジャンプ
return -1            -1を戻り値に関数から返る
fream 1              1つ前の呼び出し関数のスタックフレームに移動
thread 2             i threads で表示時のスレッド番号2番にカレントスレッドを移動
thread apply all cmd 全てのスレッドにcmdで指定したコマンドを実行
list sub.h:funcA     sub.hのfuncA関数の辺りを表示する
list sub.h:123       sub.hの123行目辺りを表示する
for string           ソース中からstringを前方検索
rev string           ソース中からstringを後方検索
shell                shellモード
attach PID           実行中のプロセスにアタッチして停止する
detach               アタッチを終了してプロセスを解放する
generate-core-file   coreを吐かせる
directory dirName    ソース検索pathにdirNameディレクトリを追加
source file          コマンドの書かれたfileを実行する(起動時実行は-xで指定)
file fileName        fileNameを新たにdebug対象とシンボルファイルとする
end                  commands,define,document,else,if,whileの実行を中止
kill                 デバッグ中のプロセスを終了する
edit 123             環境変数EDITORに指定されたエディターを開き123行目を表示。
ウチの環境ではカレントディレクトリの終りのスラッシュが見付からずに、新規ファイルを開きます:'(

q                    GDBの終了


情報表示

p a                 カレントフレームのローカル変数aの中身を表示(同名のグローバル変数が有った場合)
p 'main.c'::a       main.cファイルに書かれたグローバル変数aの中身を表示
p /x $eax           eaxレジスタの内容を16進表示
p pCA->x            構造体(クラス)ポインタpCAのメンバーxの値を表示
p (int)*(0xbffff940)    アドレス0xbffff940をintとして表示
p funcA             funcA関数のアドレスを表示
p funcA(123)        123を第一引数にfuncA関数の戻り値を表示
p array[2]          配列arrayの3番目の内容を表示
p *array@3          配列arrayの内容を先頭から3つ表示
ptype a             aの型を表示
watch i             変数iへの書き込み時にブレイク
rwatch i            変数iへの読み込み時にブレイク
awatch i            変数iへの読み書き時にブレイク
show listsize       ソースを何行表示するかを表示
show convenience    コンビニエンス変数の一覧表示
x 0xbffff940        アドレス0xbffff940の中を表示
x /8b &a            変数aのアドレスの内容をバイト単位で8個表示(bytes)
x /5h &a            2バイト(halfWords)の単位で5個表示
x /2w &a            4バイトの単位で2個表示(words)
x /3g &a            8バイトの単位で3個表示(giant words)
x /16bt  0xbffff940    アドレス0xbffff940を16バイト分2進数で表示


感想:
pは後続の式が評価され(代入文は実際にメモリに代入される)、xはアドレス内容をそのまま見るという感じかなぁ。
代入文は、set valueと打つよりpの方が早いので楽かも。この場合戻り値がvoidだとヒストリー変数が無駄に消費されてしまうので、それを回避するにはpを使わずcallを使う。
call a=123 ってコールしてる感じがしないのですが… まあ print a=123 も変な気はします。

フォーマット

a        16進の絶対アドレスとして表示する.また,同時に最も近いシ ンボルからの相対アドレスとしても表示する.これによって,指定したアドレスがどの関数にあるかが分かる.
c        整数を文字定数として表示.
d        符号つき10進数の整数として表示.
f        浮動小数点数として表示.
i        マシン語命令として表示
o        8進数として表示.
s        NULLストップ前提で文字列表示。
t        2進数として表示.
u        符号なし10進数の整数として表示.
x        正数値を16進数で表示.

一言:
単位バイト数が被らないようされている感じ。dが既出だからダブルワードがジャイアントワードだったり。


値ヒストリー

show values 15		表示した変数のヒストリーから5番目を中心に10個表示
p $ 最新のヒストリの値.
p $$ $の直前のヒストリの値.
p $$3 3個前のヒストリの値.$$1は$$と等しく,$$0は$と等しい

インフォメーション

i b                ブレークポイント情報表示
i variables        グローバル変数情報表示
i locals            ローカル変数情報表示
i frame            カレントのスタックフレーム情報表示
i break            ブレークポイント情報
i threads          スレッド情報表示
i catch            例外情報表示
i files            セクションのアドレスなどのファイル情報表示。
i address funcA    funcAのアドレスを表示
i registers        レジスターの内容を表示
i all-regsters     全てのレジスターの内容を表示
i args             現在のフレームの引数を表示
i proc all         デバッギーのプロセス情報とメモリマップの表示
i


値設定

set variable a=123     変数aに123を入れる。set a=123だと曖昧(Ambiguous)だと怒られる
p a=123                変数aに123を入れる。上記の曖昧さはsetがgdbの設定変数と衝突する可能性がある
set $eax=0xffff        eaxレジスタにffffを入れる
set $AAA=0xffff        コンビニエンス変数AAAに ffffを入れる
set args -lrt abc.txt  プロセスの起動オプションに"-lrt abc.txt"を渡す
set listsize 34        ソース表示行数の設定値に34を入れる
set $name=123          コンビニエンス変数nameに123を入れる                       
set history filename fname
デフォルトでは環境変数GDBHISTFILEの値になりますが、 この変数が設定されていない場合には`./.gdb_history'

TUI

layout asm        アセンブラウインドウを表示
layout regs       レジスタウインドウを表示
layout src        ソースウインドウを表示
layout split      ソースとアセンブリウインドウを表示
focus asm         アセンブラーウインドウにフォーカスを移動(カーソルキーで動ける)
tui reg float     浮動小数点レジスタを表示
tui reg system    システムレジスタを表示
tui reg general   汎用レジスタを表示
tui reg next      色んなレジスタ表示(SSEとか機種依存)
refresh           ウインドウのリフレッシュ。C-L
update            ソースウインドウの更新
winheigth cmd +10 コマンドウインドウのサイズを+10
C-x C-a           tuiのオンオフ

感想:
tui最高。と言った感じですが、候補一覧をバックスクロールする方法がわからないので、ちょっと辛い。さらにemacsで開いた時にtuiみたいな事(ソースだけじゃなくアセンブラやレジスタもウインドウ表示)が出来るといいんだけど、やり方がわからない:-(

         

ブレークポイント

b main           main関数でブレイク
hb main          main関数でハードウェアブレイク(EEPROM/ROMのデバッグ時に)
b sub.h:funcA    sub.hというファイルのfuncAという関数でブレイク(ファイル名で特定する場合はシングルクォートを着けずにtab補間する)
b 'CA::funcA()'    クラスCAのfuncA()関数でブレイク(クラス名で特定する場合はシングルクォートを着けてtab補間する)
b 123            カレントなソースファイルの123行目でブレイク
d 1              1番目のブレークポイントを削除。引数無しだと全削除(delete)
dis 1            1番目のブレークポイントを無効。引数無しだと全無効(disable)
ena 1            1番目のブレークポイントを有効。引数無しだと全有効(enable)
b 456 if i == j 456行目に来た時にiとjが等しければブレイク
condition 2 j<0  2番目のブレークポイントにj<0という条件を付加
condition 2      2番目のブレークポイントの条件を削除
ignore 1 23      1番目のブレークポイントを24回目の到達時にブレイク
commands 7       7番目のブレークポイントに来たらebxレジスタの中を表示
> p $ebx
> end          
rbr [Ff]unc*     正規表現でブレイクポイントを指定
catch catch      例外を受けた時に停止する
catch throw      例外が投げられた時に停止する
tb funcA         一時ブレイクポイント。到達したらブレイクポイントを削除する
tc catch         一時キャッチポイント。到達したらキャッチポイントを削除する

watch *(0xbffff95c)    アドレスbffff95cが書き換えられたらブレイク
awatch a               aが読み書きされたらブレイク
rwatch a               aが読まれたらブレイク

マクロ

define myMacro
>set $AAA=0
>if a == b
 >echo same
 >else
 >echo no same
 >end
>while a>10
 >echo still BIG
 >end
>set $AAA=$AAA+1
>end



GDBとGAS

GDBGAS
レジスター$eax%eax
変数のアドレス値&a$a




備考

コンパイル時に-gオプションが無くてもAssemblerレ ベルではデバッグ出来る

runしたときにgdbの起動引数やfileコマンドで指定したファイルのタイムスタンプが変わっているとgdbはそのファイルを再読み込みする.このと きbreakポイントなどは保持しようとする.

■Assembler

GDB標準レジスター

$pc    プログラムカウンター
$ps    プロセッサーステータス
$fp    フレームポインター
$sp    スタックポインター

例:
display /x $eax        eaxレジスターの内容を毎ステップ表示
display /i $pc         次の命令を毎ステップ表示
b label03              label03というラベルでブレイク
si                     
ni
set $eax=0xffff



■C++

b 'C[tab]            メンバー関数名補間にはシングルクォートを付ける
b _ZN2CA6setterEi    マングルネームで指定も出来る


catch catch



■GUIフロントエンド

DDD

最右翼。いいんじゃないでしょうか。

wdb

仕事場でちょっとだけ触ってます。

xgdb

うちの環境では起動しません:'(




総括:

書ききらない。というか調べきれない。
やっぱり英語が出来ないとダメか?>俺



戻 る