Oracle Solaris Studio 12.2: dbx コマンドによるデバッグ

ブレークポイントを設定する

dbx では、ブレークポイントを設定するため、3 種類のコマンドを使用することができます。

stopwhen、および trace コマンドはすべて、イベントの指定を引数として取ります。イベントの指定は、ブレークポイントのベースとなるイベントを説明しています。イベント指定の詳細については、「イベント指定の設定」を参照してください。

マシンレベルのブレークポイントを設定するには、stopiwheni、および tracei コマンドを使用します (第 18 章機械命令レベルでのデバッグを参照)。


注 –

Java コードと C JNI (Java Native Interface) コードまたは C++ JNI コードの混在するアプリケーションをデバッグする場合に、まだ読み込まれていないコードでブレークポイントを設定することができます。これらのコードへのブレークポイントの設定の詳細については、「ネイティブ (JNI) コードでブレークポイントを設定する」を参照してください。


ソースコードの特定の行に stop ブレークポイントを設定する

stop at コマンドを使用して、行番号にブレークポイントを設定します。ここで、n はソースコードの行番号、filename は任意のプログラムファイル名修飾子です。


(dbx) stop at filename:n

次に例を示します。


(dbx) stop at main.cc:3

指定された行が、ソースコードの実行可能行ではない場合、dbx は次の有効な実行可能行にブレークポイントを設定します。実行可能な行がない場合、dbx はエラーを出します。

停止場所を確認するには、file コマンドで現在のファイルを設定し、list コマンドで停止場所とする関数を表示させます。次に、stop at コマンドを使用してソース行にブレークポイントを設定します。


(dbx) file t.c
(dbx) list main
10    main(int argc, char *argv[])
11    {
12        char *msg = "hello world\n";
13        printit(msg);
14    }
(dbx) stop at 13

at an location イベントを指定する詳細については、at [filename: ]line_numberを参照してください。

関数に stop ブレークポイントを設定する

stop in コマンドを使用して、関数にブレークポイントを設定します。


(dbx) stop in function

指定関数中で停止するブレークポイントは、プロシージャまたは関数の最初のソース行の冒頭でプログラムの実行を中断します。

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() のどちらを意味しているのかを判断することができないため、オーバーロードしたメニューを表示します。

in function イベントを指定する詳細については、in function を参照してください。

C++ プログラムに複数のブレークポイントを設定する

異なるクラスのメンバー関数の呼び出し、特定のクラスのすべてのメンバー関数の呼び出し、または多重定義されたトップレベル関数の呼び出しに関連する問題が発生する可能性があります。このような場合に対処するために、inmemberinclassinfunction または inobject のキーワードのうちの 1 つを stopwhen、または trace コマンドとともに使用することにより、1 回のコマンドで C++ コードに複数のブレークポイントを挿入できます。

異なるクラスのメンバー関数にブレークポイントを設定する

特定のメンバー関数のオブジェクト固有のもの (同じメンバー関数名でクラスの異なるもの) それぞれにブレークポイントを設定するには、stop inmember を使用します。

たとえば、関数 draw が複数の異なるクラスに定義されている場合は、それぞれの関数ごとにブレークポイントを設定します。


(dbx) stop inmember draw

inmember または inmethod イベントを指定する詳細については、inmember function inmethod functionを参照してください。

クラスのすべてのメンバー関数にブレークポイントを設定する

特定のクラスのすべてのメンバー関数にブレークポイントを設定するには、stop inclass コマンドを使用します。

デフォルトでは、ブレークポイントはクラスで定義されたクラスメンバー関数だけに挿入され、ベースクラスから継承した関数には挿入されません。ベースクラスから継承した関数にもブレークポイントを挿入するには、-recurse オプションを指定します。

クラス shape で定義されたすべてのメンバー関数にブレークポイントを設定するには、次のように入力します。


(dbx) stop inclass shape

クラス shape で定義されたすべてのメンバー関数およびクラスから継承する関数にブレークポイントを設定するには、次のように入力します。


(dbx) stop inclass shape -recurse

inclass イベントを指定する詳細については、inclass classname [-recurse | -norecurse]および stop コマンド」を参照してください。

stop inclass およびその他のブレークポイントを選択することにより、大量のブレークポイントが挿入される場合があるため、dbx 環境変数 step_events を必ず on に設定し、step および next コマンドの実行速度を上げるようにしてください (「イベント効率」参照)。

非メンバー関数に複数のブレークポイントを設定する

多重定義された名前を持つ非メンバー関数 (同じ名前を持ち、引数の型または数の異なるもの) に複数のブレークポイントを設定するには、stop infunction コマンドを使用します。

たとえば、C++ プログラムで sort() という名前の関数が 2 種類定義されていて、一方が int 型の引数、もう一方が float 型の引数をとる場合に、両方の関数にブレークポイントを置くためには、次のように入力します。


(dbx) stop infunction sort 

infunction イベントを指定する詳細については、infunction functionを参照してください。

オブジェクトにブレークポイントを設定する

In Object ブレークポイントを設定し、特定のオブジェクトインスタンスに適用する操作をチェックします。

デフォルトでは、In Object ブレークポイントは、オブジェクトからの呼び出し時に、オブジェクトのクラス (継承されたクラスも含む) のすべての非静的メンバー関数でプログラムを中断します。継承クラスを除くオブジェクトのクラスで定義された非静的メンバー関数だけでプログラムの実行を中断するには、-norecurse オプションを指定します。

オブジェクト foo のベースクラスで定義されたすべての非静的メンバー関数と、オブジ ェクト foo の継承クラスで定義されたすべての非静的メンバー関数にブレークポイントを設定するには、次のように入力します。


(dbx) stop inobject &foo

オブジェクト foo の継承クラスを除く、オブジェクト foo のクラスで定義されたすべての非静的メンバー関数だけにブレークポイントを設定するには、次のように入力します。


(dbx) stop inobject &foo -norecurse

inobject イベントの指定方法の詳細については、inobject object-expression [-recurse | -norecurse] および stop コマンド」を参照してください。

データ変更ブレークポイントを設定する

dbx でデータ変更ブレークポイントを使用すると、変数値や式がいつ変更されたかをメモしておくことができます。

特定アドレスへのアクセス時にプログラムを停止する

特定のメモリーアドレスがアクセスされたときにプログラムを停止するには、次のように入力します。


(dbx) stop access mode address-expression [, byte-size-expression]

mode はメモリーのアクセス方法を指定します。次の文字 (複数可) で構成されます。

r

指定したアドレスのメモリーが読み取られたことを示します。

w

メモリーへの書き込みが実行されたことを示します。

x

メモリーが実行されたことを示します。

さらに mode には、次のいずれかの文字も指定することができます。

a

アクセス後にプロセスを停止します (デフォルト)。

b

アクセス前にプロセスを停止します。

いずれの場合も、プログラムカウンタはアクセスしている命令をポイントします。「前」と「後」は副作用を指しています。

address-expression は、その評価によりアドレスを生成できる任意の式です。シンボル式を使用すると、監視される領域のサイズが自動的に推定されます。このサイズは、byte-size-expression を指定することにより、上書されます。シンボルを使用しない、型を持たないアドレス式を使用することもできますが、その場合はサイズを指定する必要があります。

次の例では、メモリーアドレス 0x4762 以降の 4 バイトのいずれかが読み込まれたあとにプログラムが停止します。


(dbx) stop access r 0x4762, 4

次の例では、変数 speed に書き込みが行われる前にプログラムが停止します。


(dbx) stop access wb &speed

stop access コマンドを使用する場合、次の点に注意してください。

access イベントを指定する詳細については、access mode address-expression [, byte-size-expression ]および stop コマンド」を参照してください。

変数の変更時にプログラムを停止する

指定した変数の値が変更された場合にプログラム実行を停止するには、次のように入力します。


(dbx) stop change variable

stop change コマンドを使用する場合、次の点に注意してください。

change イベントを指定する詳細については、change variable および stop コマンド」を参照してください。

dbx は、自動シングルステップを実行し、各ステップで値をチェックすることにより、stop change を実装します。ライブラリが -g オプションでコンパイルされていない場合、ステップ実行においてライブラリの呼び出しが省略されます。そのため、制御が次のように流れていく場合、dbx はネストされた user_routine2 をトレースしません。トレースにおいて、ライブラリの呼び出しとネストされた user_routine2 の呼び出しが省略されるからです。


   user_routine calls
      library_routine, which calls
        user_routine2, which changes variable

variable の値の変更は、user_routin2 が実行されている最中ではなく、ライブラリが呼び出しから戻ったあとに発生したように見えます。

dbx は、ブロック局所変数 ({} でネストされている変数) の変更に対しブレークポイントを設定できません。「ネスト」されたブロック局所変数でブレークポイントまたはトレースを設定しようとすると、その操作を実行できない旨を伝えるエラーメッセージが表示されます。


注 –

change イベントよりも access イベントを使用した方が、迅速にデータ変更をチェックできます。自動的にプログラムのシングルステップを実行する代わりに、access イベントはハードウェアまたはオペレーティングシステムのはるかに高速なサービスを利用します。


条件付きでプログラムを停止する

条件文が真と評価された場合にプログラムを停止するには、次のように入力します。


(dbx) stop cond condition

condition が発生すると、プログラムは処理を停止します。

stop cond コマンドを使用する場合、次の点に注意してください。

condition イベントを指定する詳細については、cond condition-expression および stop コマンド」を参照してください。