ナビゲーションリンクをスキップ | |
印刷ビューの終了 | |
Oracle Solaris Studio 12.3: dbx コマンドによるデバッグ Oracle Solaris Studio 12.3 Information Library (日本語) |
dbx では、ほとんどのイベント管理コマンドが event filter 修飾子をオプションでサポートします。もっとも単純なフィルタは、プログラムがブレークポイントかトレースハンドラに到達したあと、またはデータ変更ブレークポイントが発生したあとに、dbx に対してある特定の条件をテストするように指示します。
このフィルタの条件が真 (非 0) と評価された場合、イベントコマンドが適用され、プログラムはブレークポイントで停止します。条件が偽 (0) と評価された場合、dbx は、イベントが発生しなかったかのようにプログラムの実行を継続します。
フィルタを含む行または関数にブレークポイントを設定するには、オプションの -if condition 修飾文を stop コマンドまたは trace コマンドの末尾に追加します。
condition には、任意の有効な式を指定できます。コマンドの入力時に有効だった言語で書かれた、ブール値または整数値を返す関数呼び出しも有効な式に含まれます。
in や at など位置に基づくブレークポイントでは、条件の構文解析を行うスコープはブレークポイント位置のスコープになります。それ以外の場合、イベントではなくエントリ発生時のスコープになります。スコープを正確に指定するために逆引用符演算子 (「逆引用符演算子」を参照) を使用する必要があることがあります。
次の 2 つのフィルタは異なります。
stop in foo -if a>5 stop cond a>5
前者は foo にブレークポイントが設定され、条件を検査します。後者は自動的に条件を検査します。
関数呼び出しをブレークポイントフィルタとして使用できます。次の例では、文字列 str の値が abcde の場合、プログラムが関数 foo() で停止します。
(dbx) stop in foo -if !strcmp(“abcde”,str)
局所変数にデータ変更ブレークポイントを配置する際に、フィルタを使用すると便利です。次の例では、現在のスコープは関数 foo() にあり、対象となる変数 index は関数 bar() にあります。
(dbx) stop access w &bar`index -in bar
bar`index により、関数 foo にある index() 変数や index という名称のグローバル変数ではなく、関数 bar にある index 変数が確実に取り出されます。
-in bar には、次のような意味があります。
関数 bar() が入力されると、ブレークポイントが自動的に有効になる。
bar() とそれが呼び出したすべての関数が有効の間は、ブレークポイントは有効の状態を保つ。
bar() からの復帰時に、ブレークポイントは自動的に無効になる。
index に対応するスタック位置は、ほかのいずれかの関数のいずれかの局所変数によって再度利用できます。-in により、ブレークポイントが起動するのは bar`index がアクセスされた場合のみになります。
最初のうちは、条件付イベントコマンド (watch タイプのコマンド) の設定と、フィルタの使用とを混同してしまうかもしれません。概念的には、watch タイプのコマンドは、各行の実行前に検査される「前提条件」を作成します (watch のスコープ内で)。ただし、条件付トリガーのあるブレークポイントコマンドでも、それに接続するフィルタを持つことができます。
次に具体的な例を示します。
(dbx) stop access w &speed -if speed==fast_enough
このコマンドは、変数 speed を監視するように dbx に指令します。speed に書き込みが行われると (watch 部分)、-if フィルタが有効になります。dbx は speed の新しい値が fast_enough と等しいかどうかチェックします。等しくない場合、プログラムは実行を継続し、stop を「無視」します。
dbx 構文では、フィルタはブレークの「事後」、構文の最後で [-if condition] 文の形式で指定されます。
stop in function [-if condition]
マルチスレッドプログラムでブレークポイントに関数呼び出しを含むフィルタを設定すると、dbx がブレークポイントに達するとすべてのスレッドの実行が停止し、条件が評価されます。条件が合致して関数が呼び出されると、dbx がその呼び出し中すべてのスレッドを再開します。
たとえば、次のブレークポイントを、多くのスレッドが lookup() を呼び出すマルチスレッドアプリケーションで設定する場合があります。
(dbx) stop in lookup -if strcmp(name, “troublesome”) == 0
dbx は、スレッド t@1 が lookup() を呼び出して条件を評価すると停止し、strcmp() を呼び出してすべてのスレッドを再開します。dbx が関数呼び出し中に別のスレッドでブレークポイントに達すると、次のいずれかの警告が表示されます。
event infinite loop causes missed events in the following handlers: ...
Event reentrancy first event BPT(VID 6m TID 6, PC echo+0x8) second event BPT*VID 10, TID 10, PC echo+0x8) the following handlers will miss events: ...
そのような場合、条件式内で呼び出された関数が mutex を取得しないことを確認できる場合は、-resumeone イベント指定修飾子を使用して、dbx がブレークポイントに達した最初のスレッドのみを再開させることができます。たとえば、次のブレークポイントを設定する場合があります。
(dbx) stop in lookup -resumeone -if strcmp(name, “troublesome”) == 0
-resumeone 修飾子はすべての場合において問題を防ぐことはしません。たとえば、次の場合にも何も行いません。
条件で再帰的に lookup() を呼び出すため、最初のスレッドと同じスレッドで lookup() の 2 つ目のブレークポイントが発生した場合。
条件実行が別のスレッドへの制御を放棄するスレッド。
イベント修飾子の詳細については、「イベント指定のための修飾子」を参照してください。