[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ユーザ・プログラムの中に誤りのある箇所を見つけると、 その明らかな誤りを訂正することで、 その後の実行が正しく行われるかどうかを知りたくなるでしょう。 GDBにはプログラムの実行に変化を与える機能があり、 これを使って実験することで、 その答を知ることができます。
例えば、 変数やメモリ上のある箇所に新しい値を格納すること、 ユーザ・プログラムにシグナルを送ること、 ユーザ・プログラムを異なるアドレスで再起動すること、 関数が完全に終了する前に呼び出し元に戻ることなどが可能です。
11.1 変数への代入 | ||
11.2 異なるアドレスにおける処理継続 | ||
11.3 ユーザ・プログラムへのシグナルの通知 | ||
11.4 関数からの復帰 | ||
11.5 プログラム関数の呼び出し | ||
11.6 プログラムへのパッチ適用 |
ある変数の値を変更するには、 代入式を評価します。 See section Expressions。 例えば、
print x=4 |
は、
変数x
に値4を格納してから、
その代入式の値
(すなわち4)
を表示します。
サポートされている言語の演算子の詳細情報については、
See section Using GDB with Different Languages。
代入の結果を表示させることに関心がなければ、
print
コマンドの代わりにset
コマンドを使用してください。
実際のところset
コマンドは、
式の値が表示もされず、
値ヒストリ
(see section Value history)
にも入らないということを除けば、
print
コマンドと同等です。
式は、
その結果の入手だけを目的として評価されます。
set
コマンドの引数となる文字列の先頭の部分が、
set
コマンドのサブ・コマンドの名前と一致してしまうような場合には、
ただのset
コマンドではなくset variable
コマンドを使用してください。
このコマンドは、
サブ・コマンドを持たないという点を除けば、
set
コマンドと同等です。
例えば、
ユーザ・プログラムにwidth
という変数がある場合、
`set width=13'によってこの変数に値を設定しようとするとエラーになります。
これは、
GDBがset width
というコマンドを持っているためです。
(gdb) whatis width type = double (gdb) p width $4 = 13 (gdb) set width=47 Invalid syntax in expression. |
ここで不正な表現となっているのは、
もちろん`=47'の部分です。
プログラム内の変数width
に値を設定するには、
以下のようにしてください。
(gdb) set var width=47 |
GDBは、 代入時の暗黙の型変換をC言語よりも多くサポートしています。 整数値を自由にポインタ型変数に格納できますし、 その逆もできます。 また、 任意の構造体を、 同じサイズの別の構造体、 または、 より小さいサイズの別の構造体に変換することができます。
メモリ上の任意の箇所に値を格納するには、
指定されたアドレスにおいて指定された型の値を生成するために、
`{…}'を使用します
(see section Expressions)。
例えば{int}0x83040
は、
メモリ・アドレス0x83040
を整数値として参照します
(メモリ上における、
ある特定のサイズと表現を示唆しています)。
また、
set {int}0x83040 = 4 |
は、 そのメモリ・アドレスに値4を格納します。
通常、
ユーザ・プログラムを継続実行するには、
continue
コマンドを使用して、
停止した箇所から継続実行させます。
以下のコマンドを使用することで、
ユーザが選択したアドレスにおいて実行を継続させることができます。
jump linespec
linespecで指定される行において、
実行を再開します。
その行にブレイクポイントが設定されている場合には、
実行は再びすぐに停止します。
linespecの形式については、
See section Printing source lines。
一般的な慣例として、
jump
コマンドは、
tbreak
コマンドと組み合わせて使用されます。
See section Setting breakpoints。
jump
コマンドは、
カレントなスタック・フレーム、
スタック・ポインタ、
メモリ内の任意の箇所の内容、
プログラム・カウンタを除くレジスタの内容を変更しません。
linespecで指定される行が、
現在実行されている関数とは異なる関数の中にある場合、
それら2つの関数が異なるパターンの引数やローカル変数を期待していると、
奇妙な結果が発生するかもしれません。
このため、
指定された行が、
現在実行されている関数の中にない場合、
jump
コマンドは実行の確認を求めてきます。
しかし、
ユーザがプログラムのマシン言語によるコードを熟知していたとしても、
奇妙な結果の発生することが予想されます。
jump *address
addressで指定されるアドレスにある命令から、 実行を再開します。
レジスタ$pc
に新しい値を設定することで、
jump
コマンドとほとんど同等の効果を実現することができます。
両者の違いは、
レジスタ$pc
に値を設定しただけでは、
ユーザ・プログラムの実行は再開されないという点にあります。
ユーザが実行を継続するときに、
プログラムが実行を再開するアドレスが変更されるだけです。
例えば、
set $pc = 0x485 |
を実行すると、
次にcontinue
コマンドやステップ実行を行うコマンドが実行されるとき、
ユーザ・プログラムが停止したアドレスにある命令ではなく、
アドレス0x485
にある命令から実行されることになります。
See section Continuing and stepping。
jump
コマンドが最も一般的に使用されるのは、
既に実行されたプログラム部分を、
さらに多くのブレイクポイントを設定した状態で再実行する場合でしょう。
これにより、
実行される処理の内容をさらに詳しく調べることができます。
signal signal
実行を停止した箇所からユーザ・プログラムを再開させますが、
すぐにsignalで指定されるシグナルを通知します。
signalには、
シグナルの名前または番号を指定できます。
例えば、
多くのシステムにおいて、
signal 2
とsignal SIGINT
はどちらも、
割り込みシグナルを通知する方法です。
一方、
signalが0であれば、
シグナルを通知することなく実行を継続します。
ユーザ・プログラムがシグナルのために停止し、
通常であれば、
continue
コマンドによって実行を再開するとそのシグナルを検知してしまうような場合に便利です。
`signal 0'を実行すると、
プログラムはシグナルを受信することなく実行を再開します。
signal
を実行した後、
RETキーを押しても、
繰り返し実行は行われません。
signal
コマンドを実行することは、
シェルからkill
ユーティリティを実行するのと同じではありません。
kill
によってシグナルを送ると、
GDBはシグナル処理テーブルによって何をするべきかを決定します
(see section シグナル)。
一方、
signal
コマンドは、
ユーザ・プログラムに直接シグナルを渡します。
return
return expression
return
コマンドによって、
呼び出されている関数の実行をキャンセルすることができます。
式expressionを引数に指定すると、
その値が関数の戻り値として使用されます。
return
を実行すると、
GDBは選択されているスタック・フレーム
(および、
その下位にあるすべてのフレーム)
を破棄します。
破棄されたフレームは、
実行を完結する前に復帰したのだと考えればよいでしょう。
戻り値を指定したいのであれば、
その値をreturn
への引数として渡してください。
このコマンドは、 選択されているスタック・フレーム (see section Selecting a frame)、 および、 その下位にあるすべてのフレームをポップして、 もともと選択されていたフレームを呼び出したフレームを、 最下位のフレームにします。 つまり、 そのフレームが選択されることになります。 指定された値は、 関数から戻り値を返すのに使用されるレジスタに格納されます。
return
コマンドは実行を再開しません。
関数から復帰した直後の状態で、
プログラムを停止したままにします。
これに対して、
finish
コマンド
(see section Continuing and stepping)は、
選択されているスタック・フレームが自然に復帰するまで、
実行を再開、
継続します。
call expr
void
型の戻り値を表示することなく、
式exprを評価します。
ユーザ・プログラムの中からある関数を呼び出したいが、
void型の戻り値を出力させたくない場合、
このprint
コマンドの変種を使用することができます。
void
型でない戻り値は表示され、
値ヒストリに保存されます。
A29Kでは、
ユーザに制御される変数call_scratch_address
によって、
GDBがデバッグ対象の関数を呼び出すときに使用するスクラッチ領域が指定されます。
通常はスクラッチ領域をスタック上に置きますが、
この方法は命令空間とデータ空間を別々に持つシステム上では機能しないため、
これが必要になります。
デフォルトでは、 GDBはユーザ・プログラムの実行コードを持つファイル (あるいは、 コア・ファイル) を書き込み不可の状態でオープンします。 これにより、 マシン・コードを誤って変更してしまうことを防ぐことができます。 しかし、 ユーザ・プログラムのバイナリに意図的にパッチを適用することもできなくなってしまいます。
バイナリにパッチを適用したいのであれば、
set write
コマンドによって明示的にそのことを指定することができます。
例えば、
内部的なデバッグ・フラグを立てたり、
緊急の修正を行いたいということがあるでしょう。
set write on
set write off
`set write on'を指定すると、 GDBは実行ファイル やコア・ファイル を、 読み込み、 書き込みともに可能な状態でオープンします。 `set write off' (デフォルト) を指定すると、 GDBはこれらのファイルを読み込みしかできない状態でオープンします。
既にファイルをロード済みの場合、
set write
の設定を変更後、
その変更を反映させるためには、
(exec-file
コマンド
、
core-file
コマンド
を使用して)、
そのファイルを再ロードしなければなりません。
show write
実行ファイル 、コア・ファイル が、 読み込みだけではなく書き込みもできる状態でオープンされる設定になっているか否かを表示します。
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated by Akihiro Sagawa on June, 15 2005 using texi2html 1.70.