gdb

GDBデバッガの使い方について説明します。

起動、引数設定

起動

起動は以下の3つの方法があります。

  1. gdb
  2. gdb 実行ファイル
  3. gdb 実行ファイル coreファイル

引数の設定

args以降に記述する。
(gdb)set args -la -ko -f ファイル名など

停止

gdbを終了します。
(gdb)quit

ステップ実行


移動方法

step ソースの異なる行に到達するまで実行する.
next その時のスタックフレーム内でソースの次の行まで実行する.
finish その時のスタックフレームがreturnするまで実行する.
until その時の次の行に到達するまで実行する.(for文などを抜け出したたい場合に便利)
return 強制的に現在の関数から抜ける。引数に復帰値を指定できる

※finisishとreturnの違い
finishは関数内の処理を実行して復帰する直前で停止するが、returnは現在の位置から強制的に復帰する。

繰り返し実行する場合
step count
stepをcountだけ実行する。
next count
nextをcountだけ実行する。


ブレークポイント

設定

ブレークポイントは以下の場所に設定できる
  • 関数名
  • 行番号
  • 現在停止している場所から前後に何行か隔てた場所
  • アドレス

例)
(gdb)break main 
(gdb)break 19
(gdb)break +offset 
(gdb)break *adress
(gdb)break test.c::20
(gdb)break test.c::func名
例)19行目に設定でi=jの時のみbreakする)
(gdb)break 19 if i == j

ブレークポイントの情報を表示

info breakで ブレークポイントの情報が表示される。
(gdb)info breakpoint [ブレークポイント番号]

表示される内容は以下である。
  • ブレークポイントの番号、タイプ
  • 廃棄(ブレークポイントが停止した際に、削除されるマークがついいているか)
  • 有効/無効
  • アドレス
  • 対象(ファイル名と行番号)

削除

ブレークポイントの削除には以下の方法がある。
  1. delete ブレークポイント番号
  2. clear 関数

例)
(gdb)delete breakpoint番号
(gdb)clear 関数


有効化・無効化

無効化
(gdb)disable breakpoint番号
有効化
(gdb)enable breakpoint番号

breakpointの条件指定

ブレークポイントの条件指定はブレークポイント設定時に決定する。
conditionコマンドを使用するといつでも設定が可能になる。
condition 番号 式
式が真の場合にのみ有効になる
(式がない場合は、条件が解除される。)

watch

watch ある式の値は変化した時に、変更箇所を特定できなくても、プログラムを停止できる。(難点として処理速度が遅い。)
※マルチスレッドの場合、単一スレッドの場合しか監視てきない。

(gdb)watch 変数

変数やソースの表示


ソースの表示

listコマンドを使用する。
指定した行から表示
  1. list 行番号
指定した関数の先頭を表示
  1. list 関数名
前回表示後から表示
  1. list
前回表示場所を表示
list -

特殊なlist表示
list ,last
last終了する文字を表示

list first,
firstで始まる行を表示

変数の表示

(gdb)p/fmt exp
expは式であり,デバッグ対象の言語と同様に記述できる.そしてfmtは出力フォーマットで,/の後に以下から選んで出力する.fmtは任意で,指定しないときは/も不要.
x 正数値を16進数で表示.
d 符号つき10進数の整数として表示.
u 符号なし10進数の整数として表示.
o 8進数として表示.
t 2進数として表示.
a 16進の絶対アドレスとして表示する.また,同時に最も近いシンボルからの相対アドレスとしても表示する.これによって,指定したアドレスがどの関数にあるかが分かる.
c 整数を文字定数として表示.
f 浮動小数点数として表示.

printでは配列(そして連続したアドレス空間)の各要素も表示できる.それには式を
(gdb)p@length

アドレスの表示

(gdb)x/nfut addres
 :n   繰り返し回数
 ;f   表示形式。printで使用される形式か、s(ヌル文字で終了する文字列)、i(マシン命令)を指定。デフォルト値は使うたびに変更される
::u   メモリサイズの単位。b(バイト),h(ハーフワード:2バイト),w(ワード:4バイト),g(ジャイアントワード:8バイト)


自動表示

ステップ実行しているときに,毎回ある変数の値を確認したいときなどがある.そういうときには自動表示をすると嬉しくなる.自動表示は以下のコマンドで行なう.
(gdb)display/fmt exp
現在何が自動表示されるかは
(gdb)display

(gdb)display exp
プログラムが停止するたびに、expが実行される。

(gdb)display/fm exp
fmに対し、表示形式を指定する。

(gdb)display/fmt adddr
fmtに対して、i,、s、メモリのサイズの単位、または単位数を指定する。(実際にはx/fmt addrが実行される)

例)
(gdb)display/i $pcを実行するとマシン命令を確認できる。
(gdb)displayで現在の設定が表示される。


変数の設定

プログラムを実行して停止したときに変数の値を設定することができる.プログラムにint変数xがあってそれを10に設定したいとすると,
(gdb)set x=10
とか(サポートしていれば)
(gdb)dprint x=10
とか(サポートしていれば)
(gdb)dset x=10
とか(サポートしていれば)
(gdb)dset variable x=10
などとする.setとset variableの違いはsetでは変数名次第でgdbコマンドとバッティングすることがあるが,set variableではそれを回避できる点である.また,それぞれの「x=10」は式であり,ここで関数呼び出しなどもできる.

コンビニエンス変数

特定の値をユーザが作成した変数に代入できる。
set $foo=*object_ptr

★★コンビニエン変数の表示
(gdb)show convenience

コマンドの略語

q quit gdbの終了
p print 変数やアドレスの表示
b break ブレークポイントの設定や情報の表示
s step ステップ実行(関数の場合は、関数内に移動)
n next ステップ実行(関数の場合でも、次の行に移動)
f finish 現在の関数から抜ける
c cont ブレークポイントで停止した状態から次のブレークポイントに移動する


ライブラリのデバッグ

ライブラリにブレークポイントを設定するには、ライブラリが呼ばれていないため認識できず、設定できない。一番簡単な方法は、
(gdb) break main
で、main関数で止めてライブラリを読んだ後でブレークポイントを設定する。
ロードされているライブラリの確認
(gdb) info sharedlibrary
ロードされているライブラリのシンボル情報の確認
(gdb) sharedlibrary
シンボルが存在しない場合は、directoryコマンドで追加して認識できるようにする。

プロセスにattach

gdbを起動したら,原則としてattachを含めて3つの手順を踏む.

  1. fileでシンボルファイルすなわちこれからattachするプロセスのシンボル情報を持っているファイルを指定する.(gdb) file attach/a.out
  2. directoryコマンドで読み込んだファイルのソースを検索できるように,ソースパスにソースのあるディレクトリを指定する. (gdb) directory attach/src/1.fileコマンドでアタッチする実行ファイルを指定する。(シンボルテーブルをロードするため)
  3. attacjコマンドでプロセスIDを指定。その際、atacchしているプロセスを停止させる。ブレークポイントのl設定や情報を調べることが可能
  4. 再びプロセスを稼動したい場合は、continueコマンドで実行する。

※attachしているプロセスを停止したときにgdbを終了してしまうと、attachしているプロセスは終了されてしまう。gdb終了時に確認のするかset confirmで設定できる

detah
attachしたプログラムが終了したら、detach処理を行う


kill gdbの子プロセスを強制終了する。ブレークポイントイの情報は維持したtまま、終了するため、再コンパイルしたファイルなどを実行する場合に便利である。killで殺して、runで実行するなどが可能である。

jump

jump 行番号
jump *address
jumpはその場所に移動する。通過した行に戻って、ブレークポイントを増やしたり、内容を表示したりするときに便利である。


マルチスレッド・マルチプロセス

マルチスレッド

gdbのまルチスレッド機能
  1. スレッド作成時の通知
  2. スレッドを切り替えるコマンド
  3. 複数のスレッドに対して1つのコマンドを実行
  4. スレッド固有のブレークポイント
マルチスレッドについて
thread threadno をブレークポイントの引数に指定すると特定のスレッドがこのブレークポイントに達したときに停止が可能

thread threadnoを指定しない場合はすべてのスレッドで停止する

あるスレッドがブレークポイントに引っかかった場合、他のスレッドはすべて停止される。
これはstepやnextでも同様である。

※gdbがスレッドに対応していない場合は、サポートされない。対応していない場合は、info threadsをしても何も表示されない。

新規にスレッドが作成された場合は、[New Process 11 threads 23]
などのメッセージが出力される。

info threadsで現在のスレッド数を表示できる。

マルチプロセス

マルチプロセスのデバッグについて
gdbでforkされた子プロセスのデバッグを実施する方法はない。
この対策として、子プロセスの起動の際に、sllepを入れて、sleepしている間に、attachする方法があるが、現在の最新のgdbなら追いかけることが可能である。

子プロセスをデバッグするには [#k3bd4614]
set follow-fork-mode mode
プログラムによるforkやvforkの呼び出しに反応するよう、デバッガを設定します。 forkやvforkの呼び出しは、新しいプロセスを生成します。 modeは、以下のいずれかです。
parent
    forkの後、元のプロセスをデバッグします。子プロセスは、妨げられることなく実行されます。これがデフォルトです。 
child
    forkの後、新しいプロセスをデバッグします。親プロセスは、妨げられることなく実行されます。


スタック

スタックについて
frame args
これは特定のスタックから別のスタックに移動したらり、洗濯したスタックフレームを表示できる。
argsはスタック番号である。

select-frame
特定にスタックフレームから別のスタックフレームに移動できるが、洗濯したフレームは表示されない。

backtrace、bt 
スタック全体のバックトレーズを表示する。引数に数字を入力すると内側のn個フレームのみ表示できる。

where、info stack などはエイリアスである。

フレームを選択する。
frame n、f n
nは0一番内側のフレーム番号、mainが一番外側になる。
(引数なしの場合、現在選択しているフレームん説明が表示される)

frame address
バグでスタックフレームの連鎖が壊れている場合は、有効である。

スタックを移動
up n
上へ移動(デフォルトは nは1)
doen n
下へ移動(デフォルトは nは1)


ブレークポイントで停止したときに自動実行


ブレークポイントで停止した際に実行するコマンドを設定できる。
command 番号
  comamandlist
end
(番号を省略した場合、最後に設定されたブレークポイントが有効になる。)
例) fooのエントリでxが整数の場合、xを表示する
command foo if x>0
   printf "x is %d",x
end

コマンドを削除する場合は、command文の後にすぐにendを入力する。

ignore

ignoreコマンドで指定した回数ブレークポイントを停止させtないことができる。
ignore 番号 通過カウント

ブレークポイントに達するたびに、通過カウントを1ずつ減らしていく。0になったら停止する。
通常のブレークポイントは通過カウントは0になっている。
条件付のブレークポイントの設定時は、通過カウントが0になるまで条件はチェックされない。

ブレークポイントで停止しているときに、そのブレークポイントを間単に変更することができる。
c 通過カウント
にすると設定可能

gdbの設定


実行するファイルを指定
file gdb起動時にファイル名を指定しなかったり、途中でファイルを変更する場合。ファイルのシンボルとメモリの内容が読み込まれる。
(引数がない場合は、現在のすべての情報を破棄する)

show gdbの状態を表示。表示される値は、setコマンドで書き換えることが可能

info args 引数を表示

実行可能プログラムはコンパイル前のソースファイル名を記憶している.GDBはソースパスからソースファイルを検索して,見つかったソースファイルを利用してソースの情報を表示する.ソースパスは以下で確認できる.
(gdb) show directories 
ソースパスを検索してもソースファイルが見つからない場合,実行可能プログラムにソースファイルのディレクトリが記録されていれば,そこを検索する.そこにもなければ,カレントディレクトリを検索する.ソースパスを追加するには,以下のコマンドを実行する.
(gdb) directory ディレクトリ名


その他

gdbのバージョンを調べる
show version

シェルのコマンドを実行
(gdb)shell echo OK

gdbのコマンドを調べる
(gdb)tcomplete i
info
inspect
ignore

プログラム中に中断する
C+Dを押して、EOを返すF

コマンドの履歴
!文字 「文字」から始まる最後に実行したコマンドを実行

  • 最終更新:2014-04-23 23:12:21

このWIKIを編集するにはパスワード入力が必要です

認証パスワード