dbx コマンドによるデバッグ | ![]() ![]() ![]() ![]() ![]() |
第 5 章
ブレークポイントとトレースの設定
ブレークポイントは、アクションが発生する場所であり、そのポイントでプログラムは実行を停止します。トレースを設定することにより、変数の値の変更など、プログラムでのイベントに関する情報を表示することができます。トレースの動作は、ブレークポイントの動作とは異なりますが、トレースとブレークポイントは同様のイベントハンドラを共有します。
この章では、ブレークポイントとトレースの設定方法とウォッチポイントの使用方法について説明します。
ブレークポイントを設定する
dbx
では、ソースレベルのブレークポイントを設定するため、3 種類のブレークポイントアクションコマンドを使用することができます。
stop
ブレークポイント -stop
コマンドによって作成されたブレークポイントに到達すると、プログラムは停止します。停止したプログラムはほかのdbx
コマンドを実行するまで再開されません。when
ブレークポイント - プログラムは停止し、dbx
が 1 つまたは複数のdbx
コマンドを実行した後、プログラムは再開します。プログラムは、コマンドの中にstop
が含まれていない限り処理を続けます。trace
ブレークポイント - プログラムは停止し、イベント固有のトレース情報行を出力した後、プログラムは再開します。マシンレベルのブレークポイントを設定するには、
stopi
、wheni
、tracei
コマンドを使用します (第 17 章を参照)。ソースコードの特定の行に
stop
ブレークポイントを設定する
dbx stop at
コマンドを使用して、行番号にブレークポイントを設定します。ここで、n はソースコードの行番号、filename は任意のプログラムファイル名修飾子です。
(dbx)
stop at
filename:n
ここで、n はソースコードの行番号、filename はそのコードが含まれているソースファイルの名前 (省略可能) です。たとえば、次のようにします。
(dbx)
stop at main.cc:3
stop
またはwhen
コマンドに指定された行が、ソースコードの実行可能行ではない場合、dbx
は次の有効な実行可能行にブレークポイントを設定します。実行可能な行がない場合、dbx
はエラーを出します。「ブレークポイント」ウィンドウ内でもブレークポイントを設定できます。詳細については、Sun WorkShop オンラインヘルプの「デバッグウィンドウの使い方」の「ブレークポイント (行に設定)」を参照してください。
関数に
stop
ブレークポイントを設定する
dbx stop in
コマンドを使用して、関数にブレークポイントを設定します。
(dbx)
stop in
function指定関数中で停止するブレークポイントは、プロシージャまたは関数の最初のソース行の冒頭でプログラムの実行を中断します。
「デバッグ」ウィンドウで、関数にブレークポイントを設定することもできます。詳細については、Sun WorkShop オンラインヘルプの「デバッグウィンドウの使い方」の「ブレークポイント (関数に設定)」を参照してください。
dbx は、以下の場合を除いては、ユーザーが参照している変数または関数を決定します。
int foo(double);int foo(int); int bar(); class x { int bar();};
stop in foo(int)グローバル関数
foo(int)
にブレークポイントを設定します。メンバー関数にブレークポイントを設定するには、次のコマンドを使用します。
stop in x::bar()
stop in foo
dbx
は、ユーザーがグローバル関数foo(int)
、グローバル関数foo(double)
のどちらを意味しているのかを判断することができず、明確にするため、オーバーロードしたメニューを表示する場合があります。
stop in ''bar
dbx
は、ユーザーがグローバル関数bar()
、メンバー関数bar()
のどちらを意味しているのかを判断することができないため、オーバーロードしたメニューを表示します。
特定の行に
when
タイプのブレークポイントを設定する
when
タイプのブレークポイントは、ほかのdbx
コマンドを副作用コマンドとして利用できます。たとえば、when
でlist
コマンドを副作用コマンドとして用いれば、独自のトレースを実現することができます。
(dbx)
when at 123 { list $lineno;}
when
はcont
コマンドを暗黙指定して動作します。上の例の場合、現在行のコードを出力した後、プログラムの実行が続けられます。動的にリンクされたライブラリにブレークポイントを設定する
実行時リンカーとの間でプログラムインタフェースを使用するコード、すなわち
dlopen()
、dlclose()
、およびそれらに関連する関数を呼び出すコードをデバッグするときは、dbx
の全機能を利用できます。実行時リンカーは、プログラムの実行中に共有ライブラリをリンクしたり、そのリンクを解除したりします。dlopen()
と
dlclose()
のサポートにより、動的にリンクされている共有ライブラリの関数もプログラムの起動時にリンクされたライブラリの関数と同様に、ステップ実行したり、ブレークポイントを設定したりできます。
dlopen
(
)
によって読み込まれるライブラリには、そのライブラリがdlopen
(
)
によって読み込まれる前にブレークポイントを設定することはできません。dlopen
(
)
によって読み込まれたフィルタライブラリには、その中の最初の関数が呼び出されるまでブレークポイントを設定することはできません。- ライブラリが
dlopen()
によって読み込まれるとき、_init()
という名前の初期化ルーチンが呼び出されます。このルーチンは、ライブラリ内のほかのルーチンを呼び出すことがあります。この初期化が終わるまで、dbx
は読み込まれたライブラリにブレークポイントを置くことができません。dlopen()
によって読み込まれたライブラリの_init()内
でdbx
を停止させることはできません。C++ プログラムに複数のブレークポイントを設定する
異なるクラスのメンバー関数の呼び出し、特定のクラスのすべてのメンバー関数の呼び出し、または多重定義されたトップレベル関数の呼び出しに関連する問題が発生する可能性があります。このような場合に対処するために、
inmember
、inclass
、infunction
またはinobject
のキーワードのうちの 1 つをstop
,when
,またはtrace
コマンドとともに使用することにより、1 回のコマンドで C++ コードに複数のブレークポイントを挿入できます。異なるクラスのメンバー関数にブレークポイントを設定する
特定のメンバー関数のオブジェクト固有のもの (同じメンバー関数名でクラスの異なるもの) それぞれにブレークポイントを設定するには、
stop inmember
を使用します。
when
ブレークポイントを設定するには、when
コマンドをキーワードinmember
とともに使用します。たとえば、関数
draw
が複数の異なるクラスに定義されている場合は、それぞれの関数ごとにブレークポイントを設定します。
(dbx)stop inmember draw
「ブレークポイント」ウィンドウで、「指定メンバー中で」ブレークポイントを設定することもできます。詳細については、Sun WorkShop オンラインヘルプの「デバッグウィンドウの使い方」の「指定メンバー中でブレークポイントの設定」を参照してください。
同じクラスのメンバー関数にブレークポイントを設定する
特定のクラスのすべてのメンバー関数にブレークポイントを設定するには、
stop
inclass
コマンドを使用します。
when
タイプのブレークポイントを設定する場合は、when
コマンドをキーワードinclass
とともに使用します。クラス wedge のすべてのメンバー関数にブレークポイントを設定するには、次のように入力します。
(dbx
)
stop inclass wedge
「ブレークポイント」ウィンドウで、「指定クラスの中で」ブレークポイントを設定することもできます。詳細については、Sun WorkShop オンラインヘルプの「デバッグウィンドウの使い方」の「指定クラスの中でプレークポイントの設定」を参照してください。
ブレークポイントは、該当するクラスで定義されているクラスメンバー関数にだけ挿入されます。基底クラスから継承された関数には挿入されません。
stop inclass
およびその他のブレークポイントを選択することにより、大量のブレークポイントが挿入される場合があるため、dbx
環境変数step_events
を必ずon
に設定し、step
およびnext
コマンドの実行速度を上げるようにしてください (「イベント効率」参照)。非メンバー関数に複数のブレークポイントを設定する
多重定義された名前を持つ非メンバー関数 (同じ名前を持ち、引数の型または数の異なるもの) に複数のブレークポイントを設定するには、
stop infunction
コマンドを使用します。
when
タイプのブレークポイントを設定する場合は、when
コマンドをキーワードinfunction
とともに使用します。たとえば、C++ プログラムで
sort()
という名前の関数が 2 種類定義されていて、一方がint
型の引数、もう一方がfloat
型の引数をとる場合に、両方の関数にブレークポイントを置くためには、次のように入力します。
(dbx)
when infunction sort {cmd;}
「ブレークポイント」ウィンドウで、「指定関数中で」ブレークポイントを設定することもできます。詳細については、Sun WorkShop オンラインヘルプの「デバッグウィンドウの使い方」の「ブレークポイント (関数に設定)」を参照してください。
オブジェクトにブレークポイントを設定する
In Object
ブレークポイントを設定して、特定オブジェクトに適用される演算を確認します。In Object
ブレークポイントは、オブジェクトから呼び出されると、そのオブジェクトクラスのすべての非静的メンバー関数によるプログラムの実行を中断します。オブジェクト
foo
にブレークポイントを設定するには、次のように入力します。
(dbx)
stop inobject &foo
「ブレークポイント」ウィンドウで、「指定オブジェクト中で」ブレークポイントを設定することもできます。詳細については、Sun WorkShop オンラインヘルプの「デバッグウィンドウの使い方」の「指定オブジェクト中でブレークポイントの設定」を参照してください。
コードをトレースする
トレースは、実行されるコード行、呼び出される関数、変更される変数についての情報を表示します。詳細については、Sun WorkShop オンラインヘルプの「デバッグウィンドウの使い方」の「コードのトレース」を参照してください。
トレースを設定する
コマンド行に
trace
コマンドを入力することにより、トレースを設定します。trace
コマンドの基本構文は次の通りです。
trace event-specification [ modifier ]トレースコマンドの完全な構文については、Sun WorkShop オンラインヘルプの「dbx コマンドの使い方」の「trace コマンド」を参照してください。
「ブレークポイント」ウィンドウで、トレースを設定することもできます。詳細については、Sun WorkShop オンラインヘルプの「デバッグウィンドウの使い方」の「トレースの設定」を参照してください。
トレースで提供される情報は、トレースに関連する event の型に依存します (「イベント指定の設定」を参照)。
トレース速度を制御する
多くのプログラムは高速に実行されるため、表示がよく見えません。環境変数
dbxenv trace_speed
を使用して、トレーススコープ内の各行の実行間隔を制御することができます。デフォルトの実行間隔は0.5
秒です。
トレース時の各行の実行間隔を設定するには、次のように入力します。
dbxenv trace_speed number「デバッグオプション」ダイアログで、トレースの実行速度を設定することもできます。詳細については、Sun WorkShop オンラインヘルプの「デバッグウィンドウの使い方」の「トレース速度の設定」を参照してください。
イベントハンドラのリストの表示とクリア
dbx
セッション中にブレークポイントやトレースポイントを複数設定することがよくあります。dbx
には、それらのポイントを表示したりクリアしたりするためのコマンドが用意されています。ブレークポイントとトレースポイントの表示
すべての有効なブレークポイントのリストを表示するには、
status
コマンドを使用します。ブレークポイントは ID 番号付きで表示され、この番号はほかのコマンドで使用できます。C++ の多重ブレークポイントのところでも説明したように、
dbx
はキーワードinmember、inclass、infunction
で設定された多重ブレークポイントを、1 つのステータス ID 番号を使用してまとめて報告します。ステータス ID 番号を使用して特定のブレークポイントを削除
status
コマンドを使用してブレークポイントをリスト表示した場合、dbx
は、各ブレークポイントの作成時に割り当てられた ID 番号を表示します。delete
コマンドを使用することで、ID 番号によってブレークポイントを削除したり、キーワードall
により、プログラム内のあらゆる場所に現在設定されているブレークポイントをすべて削除することができます。ブレークポイントを ID 番号 ID_number によって削除するには、次のように入力します。
(dbx)
delete 3 5
dbx
に現在読み込まれているプログラムに設定されているすべてのブレークポイントを削除するには、次のように入力します。
(dbx)
delete all
詳細については、Sun WorkShop オンラインヘルプの「dbx コマンドの使い方」の「delete コマンド」を参照してください。
ウォッチポイント
ウォッチポイントは、変数または式の値が変化したときにイベントを発生させる
dbx
の一般的な機能です。stop
コマンドを使用してウォッチポイントを設定することができます。アドレスの内容に書き込みが行われたときに実行を停止する
アドレスの内容に書き込みが行われたときにプログラムの実行を停止するには、次のように入力します。
(
dbx
)
stop modify
&
variable
- 変数 variable にそれまで設定されていた値と同じ値が書き込まれた場合でもイベントは発生します。
dbx
が命令をエミュレートすることによって、メモリーに新しい内容が設定された場合でも、変数への書き込みを行なった命令が実行される前にイベントが発生します。- 関数に局所的な自動変数など、スタック変数のアドレスを使用することはできません。
「ブレークポイント」ウィンドウで、「指定範囲変更時」ブレークポイントを設定することもできます。詳細については、Sun WorkShop オンラインヘルプの「デバッグウィンドウの使い方」の「指定範囲変更時に停止」を参照してください。
指定した変数の値が変化したときに実行を停止する
指定した変数の値が変化したときにプログラムの実行を停止するには、次のように入力します。
(dbx)
stop change
variable
dbx
は、指定された変数の値に変更があった行の後ろの行でプログラムを停止します。- 変数が関数の局所変数の場合、その関数に最初に制御が移り、変数のための記憶領域が割り当てられた時点で変更があったと見なします。パラメータについても、同じことが言えます。
- 「ブレークポイント」ウィンドウで、「指定変数の値変更時」ブレークポイントを設定することもできます。詳細については、Sun WorkShop オンラインヘルプの「デバッグウィンドウの使い方」の「指定変数の値変更時に停止」を参照してください。
dbx
は、自動的なステップ実行を行い、各ステップで値を検査することによって、stop change
を実現しています。ライブラリが-g
オプションでコンパイルされていない場合、ステップ実行では、ライブラリ呼び出しはスキップされます。したがって、制御の流れが次のようになっているとき、トレース時にライブラリ呼び出しと入れ子になったuser_routine2
の呼び出しがスキップされるため、dbx
は入れ子になったuser_-routine2
をトレースしません。
user_routine calls
library_routine, which calls
user_routine2, which changes variable
variable の値の変更は、
user_routine2
の途中ではなく、ライブラリ呼び出しから復帰した後に発生します。
dbx
は、ブロック局所変数、すなわち{}
内で入れ子に定義された変数の変化に対するブレークポイントは設定できません。このような変数にブレークポイント (またはトレース) を設定しようとすると、その操作ができないことを示すエラーメッセージが出されます。指定した条件が発生した場合に実行を停止する
条件文が真になったときにプログラムの実行を停止するには、次のように入力します。
(dbx)
stop cond
condition「ブレークポイント」ウィンドウで、カスタムの「指定条件成立時」ブレークポイントを設定することもできます。詳細については、Sun WorkShop オンラインヘルプの「デバッグウィンドウの使い方」の「指定条件成立時カスタムブレークポイントの設定」を参照してください。
高速
modify
イベントウォッチポイントは、
modify
イベントを使用すると簡単に設定できます。Sun WorkShop オンラインヘルプの「dbx コマンドの使い方」の「定義済みイベント」を参照してください。
modify
イベントは、プログラムを自動的にステップ実行する代わりに、はるかに高速のページ保護構造を使用します。処理速度は、デバッグ中のプログラムのシステム呼び出し率だけでなく、監視中の変数の存在するページが何回修正されるかによって異なります。ブレークポイントフィルタを設定する
dbx
では、イベント管理コマンドのほとんどで (省略可能な) イベントフィルタの修飾文も利用することができます。最も単純なフィルタは次のいずれかの時点で、dbx
に対してある特定の条件をテストするように指示します。イベント修飾子についての詳細は、「イベント指定のための修飾子」を参照してください。このフィルタ条件が真 (非 0) と評価されると、イベントコマンドが適用されます。条件が偽 (0) と評価されると、
dbx
はイベントが発生しなかったかのようにプログラムの実行を続けます。条件つきフィルタを含む行または関数にブレークポイントを設定するためには、
-if
condition 指示子文をstop
コマンドまたはtrace
コマンドの終わりに追加します。condition には、任意の有効な式を指定できます。コマンドの入力時に有効だった言語で書かれた、ブール値または整数値を返す関数呼び出しも有効な式に含まれます。
注 -in
やat
など位置にもとづくブレークポイントでは、スコープはブレークポイント位置のスコープになります。それ以外の場合、イベントではなくエントリ発生時のスコープになります。スコープを正確に指定する構文を使用しなければならないことがあります。
stop in foo -if a>5
stop cond a>5
前者は
foo
にブレークポイントが設定され、条件を検査します。後者は自動的に条件を検査します。最初のうちは、条件付イベントコマンド (watch タイプのコマンド) の設定と、フィルタの使用とを混同してしまうかもしれません。概念的には、watch タイプのコマンドは、各行の実行前に検査される前提条件を作成します (watch のスコープ内で)。ただし、条件付トリガーのあるブレークポイントコマンドでも、それに接続するフィルタを持つことができます。
(dbx)
stop modify &speed -if speed==fast_enough
このコマンドは、変数 speed を監視するように
dbx
に指令します。speed に書き込みが行われると、-if
フィルタが有効になります。dbx
は speed の新しい値がfast_enough
と等しいかどうかチェックします。等しくない場合、プログラムは実行を継続し、stop
を「無視」します。
dbx
構文では、フィルタはブレークの「事後」、構文の最後で[-if
condition]
文の形式で指定されます。
stop in
function[-if
condition]
イベント効率
デバッグ中のプログラムの実行時間に関するオーバーヘッドの量はイベントの種類によって異なります。最も単純なブレークポイントのように、実際はオーバーヘッドが何もないイベントもあります。1 つのブレークポイントしかないイベントも、オーバーヘッドは最小です。
実際のブレークポイントがときには何百にもなることのある多重ブレークポイント (
inclass
など) は、コマンド発行時にのみオーバーヘッドがあります。これは、dbx
が永続的ブレークポイントを使用するためです。永続的ブレークポイントは、プロセスに常に保持され、停止するたびに取り除かれたり、cont
のたびに置かれたりすることはありません。
注 -step
およびnext
の場合、デフォルトでは、プロセスが再開される前にすべてのブレークポイントが取り除かれ、ステップが完了するとそれらは再び挿入されます。したがって、多くのブレークポイントを使用したり、多くのクラスで多重ブレークポイントを使用したりしているとき、step
およびnext
の速度は大幅に低下します。dbxenv
変数step_events
を使用して、step
やnext
のたびにブレークポイントを取り除いたり、挿入し直したりするかどうかを制御することができます。
自動ステップ実行を利用するイベントは最も低速です。これは、各ソース行をステップ実行する単純な
trace
step
コマンドの場合と同様にはっきりしています。一方、stop
change
expression やtrace
cond
variable (ウォッチポイントと呼ばれるイベントのクラス) のようなイベントは、自動的にステップ実行するだけでなく、各ステップで式 expression や変数 variable を評価する必要があります。これらのイベントは非常に低速ですが、イベントと修飾語
-in
を使用した関数とを結び付けることで、効率が上がることがよくあります。たとえば、次のようにします。
trace next -in mumble
stop change clobbered_variable -in lookup
trace -in main
を使用しないでください。これは、main
によって呼び出された関数の中でも、トレースが有効になるためです。関数lookup()
が変数の値を頻繁に変更すると思われる場合には、この方法を使用してください。
サン・マイクロシステムズ株式会社 Copyright information. All rights reserved. |
ホーム | 目次 | 前ページへ | 次ページへ | 索引 |