[Contents]   [Back]   [Prev]   [Up]   [Next]   [Forward]  


ソース・ファイルの検査

GDBは、 ユーザ・プログラムのソース・コードの一部を表示することができます。 これは、 プログラムの中に記録されているデバッグ情報によって、 そのプログラムをビルドするのにどのソース・ファイルが使用されたかをGDBが知ることができるからです。 ユーザ・プログラムが停止すると、 GDBは自発的にプログラムが停止した行を表示することができます。 同様に、 ユーザがあるスタック・フレーム (フレームの選択を参照) を選択すると、 そのフレームにおいて実行が停止している行をGDBは表示します。 明示的にコマンドを使用することで、 ソース・ファイルの他の部分を表示することも可能です。 GDBをGNU Emacsインターフェイス経由で使用しているユーザは、 Emacsの提供する機能を使ってソース・ファイルを参照する方を好むかもしれません。 これについては、 GNU Emacs内でのGDBの使用を参照してください。

ソース行の表示

ソース・ファイル内の行を表示するには、 listコマンド (省略形はl) を使用します。 デフォルトでは、 10行が表示されます。 ソース・ファイルのどの部分を表示するかを決定する方法がいくつかあります。 listコマンドの最もよく使われる形式を以下に示します。

list linenum
現在のソース・ファイルの行番号linenumを中心にその前後の行を表示します。
list function
関数functionの先頭を中心にその前後の行を表示します。
list
ソース・ファイル行の続きを表示します。 既に表示された最後の行がlistコマンドによって表示されたのであれば、 その最後の行の次の行以降が表示されます。 しかし、 既に表示された最後の行が、 スタック・フレーム (スタックの検査を参照) の表示の一部として1行だけ表示されたのであれば、 その行の前後の行が表示されます。
list -
前回表示された行の前に位置する行を表示します。

listコマンドを上記の形式のいずれかによって実行すると、 GDBはデフォルトでは10行のソース行を表示します。 これはset listsizeコマンドによって変更することができます。

set listsize count
listコマンドで表示される行数をcountに設定します (listコマンドの引数で他の値が明示的に指定された場合は、 この設定は効きません)。
show listsize
listコマンドが表示する行数を表示します。

listコマンドを実行後、 RETキーによってlistコマンドを実行した場合、 引数は破棄されます。 したがって、 これは単にlistと入力して実行したのと同じになります。 これは、 同じ行を繰り返し表示するよりも役に立つでしょう。 ただし、 引数`-'は例外となります。 この引数は繰り返し実行の際に維持されるので、 繰り返し実行することで、 ソース・ファイルの内容がさかのぼって表示されていきます。 一般的には、 listコマンドはユーザが0個、 1個、 もしくは2個の行仕様linespec)を指定することを期待しています。 ここで行仕様とは、 ソース行を指定するものです。 いくつかの記述方法がありますが、 いずれも結果的には何らかのソース行を指定するものです。 listコマンドの引数として使用できる引数の完全な説明を以下に示します。

list linespec
linespecによって指定される行を中心にその前後の行を表示します。
list first,last
first行からlast行までを表示します。 両引数はいずれも行仕様です。
list ,last
last行までを表示します。
list first,
first行以降を表示します。
list +
最後に表示された行の次の行以降を表示します。
list -
最後に表示された行の前の行以前を表示します。
list
前述。

以下に、 単一のソース行を指定する方法を示します。 これは、 いずれも行仕様です。

number
現在のソース・ファイルの行番号numberの行を指定します。 listコマンドの引数に2つの行仕様がある場合、 この行仕様は最初の行仕様のソース・ファイルと同一のものを指定します。
+offset
最後に表示された行からoffsetで指定される行数だけ下にある行を指定します。 2つの行仕様を引数として持つlistコマンドにおいて、 これが第2の行仕様として使用される場合、 第1の行仕様からoffsetで指定される行数だけ下の行を指定します。
-offset
最後に表示された行からoffsetで指定される行数だけ上にある行を指定します。
filename:number
ソース・ファイルfilenameの行番号numberの行を指定します。
function
関数functionの本体の先頭行を指定します。 例えばC言語では、 左括弧 (`{') のある行を指します。
filename:function
ファイルfilename内の関数functionの本体を開始する左括弧 (`{') のある行を指定します。 異なるソース・ファイルの中に同一の名前の関数が複数ある場合にのみ、 あいまいさを回避するために関数名とともにファイル名を指定する必要があります。
*address
プログラム・アドレスaddressを含む行を指定します。 addressには任意の式を指定することができます。

ソース・ファイル内の検索

カレントなソース・ファイル内において正規表現による検索を行うためのコマンドが2つあります。

forward-search regexp
search regexp
`forward-search regexp'コマンドは、 最後にlistコマンドによって表示された行の1つ下の行から、 1行ずつ正規表現regexpによる検索を行います。 正規表現にマッチするものが見つかると、 その行を表示します。 `search regexp'という同義語を使うことができますし、 コマンド名をfoと省略することもできます。
reverse-search regexp
`reverse-search regexp'コマンドは、 最後にlistコマンドによって表示された行の1つ上の行から、 1行ずつ逆方向に向かって正規表現regexpによる検索を行います。 正規表現にマッチするものが見つかると、 その行を表示します。 コマンド名をrevと省略することができます。

ソース・ディレクトリの指定

実行形式プログラムは、 それがコンパイルされたソース・ファイルの名前のみを記録して、 それらソース・ファイルの存在するディレクトリ名を記録しないことがあります。 また、 ディレクトリ名が記録された場合でも、 コンパイル時とデバッグ時との間に、 そのディレクトリが移動してしまっている可能性があります。 GDBは、 ソース・ファイルを検索すべきディレクトリの一覧を持っています。 これは、 ソース・パスと呼ばれます。 GDBは、 ソース・ファイルが必要なときにはいつでも、 それが見つかるまで、 このリストの中のすべてのディレクトリを記述されている順に探します。 実行ファイルのサーチ・パスは、 この目的では使用されないことに気をつけてください。 またカレントな作業ディレクトリも、 それがたまたまソース・パスの中にある場合を除けば、 この目的で使用されることはありません。 GDBがソース・パスの中でソース・ファイルを見つけることができない場合、 プログラムがディレクトリ名を記録してあれば、 そのディレクトリも検索されます。 ソース・パスにディレクトリの指定がなく、 コンパイルされたディレクトリの名前も記録されていない場合、 GDBは最後の手段としてカレント・ディレクトリを探します。 ソース・パスを再設定もしくは再調整した場合には、 ソース・ファイルの存在場所や個々の行のファイル内の位置など、 GDBが内部でキャッシュしている情報は消去されます。 GDBの起動時には、 ソース・パスにはディレクトリの指定がありません。 ディレクトリをソース・パスに追加するには、 directoryコマンドを使用してください。

directory dirname ...
dir dirname ...
ディレクトリdirnameをソース・パスの先頭に追加します。 複数のディレクトリを、 コロン`:'もしくは空白で区切ることによって、 このコマンドに渡すことができます。 ソース・パスの中に既に存在するディレクトリを指定することもできます。 この場合、 そのディレクトリのソース・パス内における位置が前に移動するので、 GDBはそのディレクトリの中を以前よりも早く検索することになります。 (コンパイル時のディレクトリが記録されていれば) それを指すのに文字列`$cdir'を使うことができます。 また、 カレントな作業ディレクトリを指すには、 文字列`$cwd'を使うことができます。 `$cwd'`.' (ピリオド) とは同じではありません。 前者は、 GDBセッション内においてカレントな作業ディレクトリが変更された場合、 変更されたディレクトリを指します。 これに対して後者は、 ソース・パスへの追加時に、 その時点でのカレント・ディレクトリに展開されてしまいます。
directory
ソース・パスの内容を再び空にします。 ソース・パスを空にする前に、 確認を求めてきます。
show directories
ソース・パスを表示します。 ソース・パスに含まれるディレクトリ名を見ることができます。

ソース・パスの中に、 もはや関心の対象ではないディレクトリが混在していると、 GDBが誤ったバージョンのソースを見つけてしまい、 混乱をもたらすことがあります。 以下の手順によって、 正常な状態にすることができます。

  1. ソース・パスを空にするために、 directoryコマンドを引数なしで実行します。
  2. ソース・パス中に含めたいディレクトリが組み込まれるよう、 directoryコマンドに適切な引数を指定して実行します。 すべてのディレクトリを、 1回のコマンド実行で追加することができます。

ソースとマシン・コード

info lineコマンドを使用してソース行をプログラム・アドレスに (あるいは、 プログラム・アドレスをソース行に) 対応付けすることができます。 あるいは、 disassembleコマンドを使用してあるアドレス範囲をマシン命令として表示することもできます。 GNU Emacsのモードで実行されている場合、 現在のinfo lineコマンドは、 指定された行を示す矢印を表示します。 また、 info lineコマンドは、 アドレスを16進形式だけではなくシンボリック形式でも表示します。

info line linespec
ソース行linespecに対応するコンパイル済みコードの開始アドレス、 終了アドレスを表示します。 listコマンド (ソース行の表示を参照) が理解できる任意の形式によってソース行を指定することができます。

例えば、 info lineコマンドによって、 関数m4_changequoteの最初の行に対応するオブジェクト・コードの位置を知ることができます。

(gdb) info line m4_changecom
Line 895 of "builtin.c" starts at pc 0x634c and ends at 0x6350.

また、 (linespecの形式として*addrを使用することで) ある特定のアドレスがどのソース行に含まれるのかを問い合わせることができます。

(gdb) info line *0x63ff
Line 926 of "builtin.c" starts at pc 0x63e4 and ends at 0x6404.

info lineの実行後、 xコマンドのデフォルト・アドレスは、 その行の先頭アドレスに変更されます。 これにより、 マシン・コードの調査を開始するには`x/i'を実行するだけで十分となります (メモリの調査を参照)。 また、 このアドレスはコンビニエンス変数$_の値として保存されます (コンビニエンス変数を参照)。

disassemble
この専用コマンドは、 あるメモリ範囲をマシン命令としてダンプ出力します。 デフォルトのメモリ範囲は、 選択されたフレームにおいてプログラム・カウンタが指している箇所を含む関数です。 このコマンドに引数を1つ渡すと、 それはプログラム・カウンタ値を指定することになります。 GDBは、 その値が指す箇所を含んでいる関数をダンプ出力します。 2つの引数を渡すと、 ダンプ出力するアドレス範囲 (1つめのアドレスは含まれますが、 2つめのアドレスは含まれません) を指定することになります。

disassembleコマンドを使用して、 info lineコマンドを説明した際に示した例で表示されたオブジェクト・コードの範囲を検査することができます (ここでは、 SPARCのマシン命令が示されています)。

(gdb) disas 0x63e4 0x6404
Dump of assembler code from 0x63e4 to 0x6404:
0x63e4 <builtin_init+5340>:     ble 0x63f8 <builtin_init+5360>
0x63e8 <builtin_init+5344>:     sethi %hi(0x4c00), %o0
0x63ec <builtin_init+5348>:     ld [%i1+4], %o0
0x63f0 <builtin_init+5352>:     b 0x63fc <builtin_init+5364>
0x63f4 <builtin_init+5356>:     ld [%o0+4], %o0
0x63f8 <builtin_init+5360>:     or %o0, 0x1a4, %o0
0x63fc <builtin_init+5364>:     call 0x9288 <path_search>
0x6400 <builtin_init+5368>:     nop
End of assembler dump.

set assembly-language instruction-set
このコマンドは、 disassembleコマンド、 もしくは、 x/iコマンドによってプログラムの逆アセンブルを行う際に使う命令セットを選択します。 これは、 複数のネイティブ命令セットを持つアーキテクチャにおいて役に立ちます。 現在のところ、 これはIntel x86ファミリに対してのみ定義されています。 instruction-seti386もしくはi8086に設定することができます。 デフォルトはi386です。


[Contents]   [Back]   [Prev]   [Up]   [Next]   [Forward]