イベント管理は、デバッグ中のプログラムで特定のイベントが発生したときに特定のアクションを実行する、dbx の一般的な機能です。
この付録には次のセクションが含まれています。
イベント管理は ハンドラの概念に基づきます。この名前はハードウェアの割り込みハンドラからきたものです。各イベント管理コマンドは一般にハンドラを作成し、それは イベント指定と一連の副作用アクションで構成されます。(イベント指定の設定参照)。イベント指定は、ハンドラを発生させるイベントを指定します。
イベントが発生し、ハンドラが引き起こされると、イベント指定に含まれる任意の修飾子に従って、ハンドラはイベントを評価します (イベント指定修飾子参照)。修飾子によって課された条件にイベントが適合すると、ハンドラの関連アクションが実行されます (つまり、ハンドラが起動します)。
プログラムイベントを dbx アクションに対応付ける例は、特定の行にブレークポイントを設定するものです。
ハンドラを作成するもっとも汎用的な形式は、when コマンドを使用することです。
when event-specification {action; ... }
この章の例では、when に関してコマンド (stop、step、ignore など) を書く方法を示します。これらの例は、when とその配下にある「ハンドラ」メカニズムの柔軟性を示すものですが、常に同じ働きをするとはかぎりません。
イベントハンドラを作成するには、when コマンド、stop コマンド、trace コマンドを使用します。(詳細については、when コマンド、stop コマンド、および trace コマンドを参照)。
共通の when 構文は、stop を使用して簡単に表現できます。
when event-specification { stop -update; whereami; }
event-specification は、イベント管理コマンド stop、when、trace で、目的のイベントを指定するために使用します (イベント指定の設定を参照)。
trace コマンドのほとんどは、when コマンド、ksh 機能、イベント変数を使用して手動で作成することができます。これは、スタイル化されたトレーシング出力を希望する場合、特に有益です。
すべてのコマンドは、ハンドラ ID (hid) と呼ばれる番号を返します。事前定義変数 $newhandlerid を介してこの番号にアクセスすることができます。
次のコマンドを使用して、イベントハンドラを操作することができます。各コマンドの詳細については、それぞれのセクションを参照してください。
|
イベントハンドラには、カウント制限を保持するトリップカウンタがあります。イベントが発生するたびにカウンタをインクリメント (1 つ増加) し、ハンドラに関連付けられたアクションが実行されるのは、カウントが制限値に達したときのみで、その時点でカウンタは自動的に 0 にリセットされます。デフォルトの制限値は 1 です。プロセスを再実行する際は常に、すべてのイベントカウンタがリセットされます。
カウント制限を設定するには、stop コマンド、when コマンド、trace コマンドで –count 修飾子を使用します。このほか、handler コマンドを使用して、個々のイベントハンドラを操作できます。
handler [ -count | -reset ] hid new-count new-count-limit
dbx では、イベントメカニズムによって、豊富な種類のブレークポイントが用意されていますが、内部でも多くのイベントが使用されています。これらの内部イベントのいくつかで停止することによって、dbx の内部の動作を簡単に中断することができます。さらに、これらの場合の処理状態を変更すると、中断できる機会が増えます。Appendix A, プログラム状態の変更と呼び出しの安全性を参照してください。
場合によっては、dbx は自身を保護して中断を妨げることがありますが、すべての場合ではありません。一部のイベントは下位レベルのイベントという観点で実装されています。たとえば、すべてのステップ実行は fault FLTTRACE イベントに基づきます。そのため、コマンド stop fault FLTTRACE を発行すると、ステップ実行が停止します。
デバッグに続く段階では、dbx はユーザーイベントを処理できません。これは、ユーザーイベントにより精密な内部統合が妨げられるからです。これらのフェーズに含まれるもの:
プログラムの起動時に rtld が実行された場合 (動的リンカーを参照)
プロセスの開始と終了時
fork() 関数と exec() 関数のあと (fork 機能後のプロセス追跡およびexec 機能後のプロセス追跡を参照)
dbx がユーザープロセスのヘッドを初期化する必要がある場合の呼び出し時 (proc_heap_init())
dbx がスタックのマップされたページを確実に利用できるようにする必要がある場合の呼び出し時 (ensure_stack_memory())
多くの場合、stop コマンドの代わりに when コマンドを使用して、情報を表示することができます。このコマンドを使用しない場合は、対話によって情報を取得する必要があります。
dbx は次のようにして自身を保護します。
sync、syncrtld、および prog_new イベントに stop コマンドを許可しない
rtld ハンドシェーク時および前述のその他のフェーズで stop コマンドを無視する
例:
...SolBook linebreakstopped in munmap at 0xff3d503c 0xff3d503c: munmap+0x0004: ta %icc,0x00000008SolBook linebreak dbx76: warning: 'stop' ignored -- while doing rtld handshake
$firedhandlers 変数での記録を含む停止効果のみが無視されます。カウントやフィルタはアクティブなままになります。このような場合で停止させるには、event_safety 環境変数を off に設定します。
イベント指定は、stop コマンド、stopi コマンド、when コマンド、wheni コマンド、trace コマンド、tracei コマンドで、イベントタイプとパラメータを表すために使用します。書式は、イベントタイプを表すキーワードとオプションのパラメータで構成されます。イベント指定の意味は、一般に 3 つすべてのコマンドで同じです。例外は付録 D のコマンドの説明に記載されています。
ブレークポイントとは、アクションが発生する位置であり、その位置でプログラムは実行を停止します。このセクションでは、ブレークポイントイベントのイベント指定について説明します。
in イベント指定の構文:
infunction
関数に入り、先頭行が実行される直前です。先行ログ後の最初の実行可能コードは、実際のブレークポイントの位置として使用されます。この行は、局所変数を初期化する行である場合があります。C++ のコンストラクタの場合、すべてのベースクラスのコンストラクタの実行後に実行されます。–instr 修飾子が使用された場合、それは関数の最初の命令が実行される直前です。function 仕様は、仮パラメータを含むことができるため、多重定義関数名、またはテンプレートインスタンスの指定に役立ちます。例:
stop in mumble(int, float, struct Node *)
at イベント指定の構文:
at[filename:]line-number
指定の行が実行される直前。filename を指定した場合は、指定したファイルの指定の行が実行される直前です。ファイル名には、ソースファイル名またはオブジェクトファイル名を指定します。引用符は不要ですが、ファイル名に特殊文字が含まれる場合は、必要な場合があります。指定の行がテンプレートコードに含まれる場合、ブレークポイントは、そのテンプレートのすべてのインスタンス上に置かれます。
ataddress-expression
指定のアドレスの指示が実行される直前。このイベントは stopi コマンドまたは –instr イベント修飾子でのみ使用できます。
infile イベント指定の構文:
infile filename
このイベントにより、ファイルで定義されたすべての関数にブレークポイントが設定されます。stop infile コマンドは、funcs –f filename コマンドと同じ関数のリストを繰り返します。
.h ファイル内のメソッド定義、テンプレートファイル、または .h ファイル内のプレーン C コード (regexp コマンドで使用される種類など) は、ファイルの関数定義に寄与する場合がありますが、これらの定義は除外されます。
指定されたファイル名が、オブジェクトファイルの名前の場合 (その場合、名前は .o で終了する)、ブレークポイントは、そのオブジェクトファイルで発生する関数すべてに設定されます。
stop infile list.h コマンドは、list.h ファイルで定義されたメソッドのすべてのインスタンスにブレークポイントを設定することはしません。そうするためには、inclass または inmethod のようなイベントを使用します。
fix コマンドは、関数をファイルから削除する、または追加する場合があります。stop infile コマンドは、ファイル内の関数のすべての古いバージョンと、将来追加されるすべての関数にブレークポイントを設定します。
ネストされた関数や Fortran ファイルのサブルーチンには、ブレークポイントは設定されません。
clear コマンドを使用して、infile イベントによって作成された組にある単一のブレークポイントを無効にできます。
infunction イベント指定の構文:
infunctionfunction
この指定は、function という名前のすべての多重定義関数またはそれのすべてのテンプレートインスタンスに対する in function と同等です。
inmember イベント指定の構文:
inmember function
この指定は inmethod イベント指定のエイリアスです。
inmember イベント指定の構文:
inmethod function
この指定は、すべてのクラスの function という名前のメンバーメソッドに対する in function と同等です。
inclass イベント指定の構文:
inmember classname [-recurse | -norecurse]
この指定は、classname のメンバーであるが、classname のベースのメンバーではない、すべてのメンバー関数に対する in function と同等です。デフォルトは –norecurse です。–recurse が指定された場合、基底クラスが含まれます。
inobject イベント指定の構文:
inobject object-expression [-recurse | -norecurse]
object-expression で示されるアドレスにある特定のオブジェクトに対して呼び出されたメンバー関数が呼び出されました。stop inobject ox はほぼ次と同じですが、inclass とは異なり、ox の動的タイプのベースが含まれます。–recurse はデフォルトです。–norecurse が指定された場合、基底クラスが含まれます。
stop inclass dynamic_type(ox) -if this==ox
このセクションでは、メモリーアドレスの内容へのアクセスや変更に関するイベントのイベント指定について説明します。
access イベント指定の構文:
access mode address-expression [,byte-size-expression]
address-expression で指定されたメモリーがアクセスされたとき。
mode はメモリーのアクセス方法を指定します。有効な値は次のいずれかまたはすべての文字です。
指定したアドレスのメモリーが読み取られたことを示します。
メモリーへの書き込みが実行されたことを示します。
メモリーが実行されたことを示します。
さらに mode には、次のいずれかの文字も指定することができます。
アクセス後にプロセスを停止します (デフォルト)。
アクセス前にプロセスを停止します。
いずれの場合も、プログラムカウンタは副作用アクションの前後で違反している命令をポイントします。「前」と「後」は副作用を指しています。
address-expression は、その評価によりアドレスを生成できる任意の式です。記号式を指定すると、監視対象領域のサイズが自動的に推定されます。byte-size-expression を指定して、それをオーバーライドすることができます。さらに、シンボルを使用しない、型を持たないアドレス式を使用することもできますが、その場合はサイズが必須です。例:
stop access w 0x5678, sizeof(Complex)
access コマンドには、2 つの一致する領域が重複しない、という制限があります。
change イベント指定の構文:
change variable
variable の値は変更されました。change イベントは、次とほぼ同等です。
when step { if [ $last_value !=$[variable]] then stop else last_value=$[variable] fi }
このイベントはシングルステップを使用して実装されます。パフォーマンスの向上のため、access イベントを使用してください。
最初に variable がチェックされると、変更が検出されない場合でも 1 つのイベントが発生します。この最初のイベントによって variable の最初の値にアクセスできるようになります。あとから検出された variable の値への変更によって別のイベントが発生します。
cond イベント指定の構文:
cond condition-expression
condition-expression で示された条件は true に評価されます。condition-expression には任意の式を使用できますが、整数型に評価されなければなりません。cond イベントは次の stop コマンドとほぼ同等です。
stop step -if conditional-expression
このセクションでは、システムイベントのイベント指定について説明します。
dlopen() および dlopen() イベント指定の構文:
dlopen [ lib-path ]
dlclose [ lib-path ]
システムイベントは、dlopen() の呼び出しまたは dlclose() の呼び出しが成功したあとに発生します。dlopen() の呼び出しまたは dlclose() の呼び出しにより、複数のライブラリがロードされることがあります。これらのライブラリのリストは、事前定義済み変数 $dllist でいつでも入手できます。$dllist の中の最初のシェルの単語は + (プラス記号) または - (マイナス記号) で、ライブラリのリストに追加されているか、削除されているかを示します。
lib-path は、該当する共有ライブラリの名前です。これを指定した場合、そのライブラリが読み込まれたり、読み込みが取り消されたりした場合にだけイベントが起動します。その場合、$dlobj にライブラリの名前が格納されます。また、$dllist も利用できます。
lib-path が / で始まる場合は、パス名全体が比較されます。それ以外の場合は、パス名のベースだけが比較されます。
lib-path を指定しない場合、イベントは任意の dl 動作があるときに必ず起動します。$dlobj は空になりますが、$dllist は有効です。
fault イベント指定の構文:
fault fault
fault イベントは、指定された障害が検出されたときに発生します。障害は、アーキテクチャー依存です。dbx に認識される一連の障害を次のリストに示し、proc(4) マニュアルページで定義しています。
不正命令
特権付き命令
ブレークポイントトラップ
トレーストラップ (ステップ実行)
メモリーアクセス (境界合わせなど)
メモリーアクセス (境界合わせなど)
メモリー境界 (無効なアドレス)
整数オーバーフロー
整数ゼロ除算
浮動小数点例外
修復不可能なスタックフォルト
回復可能なページフォルト
ウォッチポイントトラップ
CPU パフォーマンスカウンタオーバーフロー
これらの障害は、/sys/fault.h から抜粋されています。fault には上に挙げたいずれかを大文字または小文字、FLT- 接頭辞を付けるか付けないで指定するか、または実際の数値コードを指定できます。
lwp_exit イベント指定の構文:
lwp_exit
lwp_exit イベントは、lwp が終了したときに発生します。$lwp には、イベントハンドラの継続時間中に終了した LWP (軽量プロセス) の ID が含まれます。
sig イベント指定の構文:
sigsignal
sig signal イベントは、デバッグ中のプログラムにシグナルが初めて送られたときに、発生します。signal は、10 進数、または大文字、小文字のシグナル名のいずれかです。接頭辞はオプションです。このイベントは、catch コマンドおよび ignore コマンドからは完全に独立しています。ただし、catch コマンドは次のように実装することができます。
function simple_catch { when sig $1 { stop; echo Stopped due to $sigstr $sig whereami } }
または、サブコードでシグナルを指定することができます。sig イベント指定のこのオプションの構文:
sigsignal sub-code
指定の sub-code を持つ指定の信号が child に初めて送られたとき、sig signalsub-code イベントが発生します。シグナルと同様に、sub-code は 10 進数として、大文字または小文字で指定することができます。接頭辞はオプションです。
sysin イベント指定の構文:
sysincode|name
指定されたシステムコールが起動された直後で、プロセスがカーネルモードに入ったとき。
dbx でサポートされるシステムコールの概念は、/usr/include/sys/syscall.h に列挙されるように、カーネルへのトラップによって提供されるものです。
この概念は、ABI のシステムコールの概念とは違います。ABI のシステムコールの一部は部分的にユーザーモードで実装され、非 ABI のカーネルトラップを使用します。ただし、一般的なシステムコールのほとんど (シグナル関係は除く) は syscall.h と ABI で共通です。
/usr/include/sys/syscall.h 内のカーネルシステムコールトラップのリストは、Oracle Solaris OS のプライベートインタフェースの一部であり、リリースによって異なります。dbx が受け付けるトラップ名 (コード) およびトラップ番号のリストは、dbx がサポートするバージョンの Solaris OS によってサポートされているすべてを含みます。dbx によってサポートされている名前が特定のリリースの Solaris OS のそれらと正確に一致することはありえないため、syscall.h 内の一部の名前は使用できない場合があります。すべてのトラップ番号 (コード) は dbx で受け入れられ、予測どおりに動作しますが、既知のシステムコールトラップに対応しない場合は、警告が発行されます。
sysout イベント指定の構文:
sysoutcode|name
指定されたシステムコールが終了し、プロセスがユーザーモードに戻る直前。
引数がないときは、すべてのシステムコールがトレースされます。ここで、modify イベントや RTC (実行時検査) などの特定の dbx は、子プロセスにその目的でシステムコールを引き起こすことがあることに注意してください。トレースした場合にそのシステムコールの内容が示されることがあります。
このセクションでは、実行進行状況に関するイベントのイベント指定について説明します。
exit イベント指定の構文:
exitexitcode
next イベントは、ステップインしない関数を除いて、step イベントと似ています。
returns イベントは、現在アクセスされている関数の戻りポイントにあるブレークポイントです。表示されている関数を使用するのは、いくつかの up を行なったあとに returns イベント指定を使用できるようにするためです。通常の returns イベントは常に一時イベント (–temp) で、動作中のプロセスが存在する場合にだけ作成できます。
returns イベント指定の構文:
returnsfunction
returns function イベントは、特定の関数がその呼び出し場所に戻るたびに実行されます。これは一時イベントではありません。戻り値は示されませんが、SPARC プラットフォームでは $o0、Intel プラットフォームでは $eax を使用して、必須戻り値を調べることができます。
SPARC ベースのシステム – $o0
x86 ベースのシステム – $eax
x64 ベースのシステム – $rax、$rdx
このイベントは、次のコードとほとんど同じ働きをします。
when in func { stop returns; }
step イベントは、ソース行の最初の命令が実行されたときに発生します。たとえば、次のコマンドで簡単なトレースを取得できます。
when step { echo $lineno: $line; }; cont
step イベントを有効にするということは、次に cont コマンドが使用されるときに自動的にステップ実行できるように dbx に命令することと同じです。
throw イベントの構文:
throw [type | –unhandled | –unexpected]
throw イベントは、アプリケーションによって、処理されないか、予期しない例外がスローされるたびに発生します。
throw イベントで例外のタイプが指定されている場合、そのタイプの例外だけが throw イベントを発生させます。
–unhandled オプションが指定されている場合、例外を示す特殊な例外タイプがスローされますが、それに対してハンドラが存在しません。
–unexpected オプションが指定されている場合、例外を示す特殊な例外タイプはそれをスローした関数の例外指定を満たしていません。
次のセクションでは、追跡されたスレッドのイベント指定について説明します。
omp_barrier イベント指定は、追跡されたスレッドがバリアに入るか、出るタイミングです。type (explicit または implicit になる) と、state (enter、exit、または all_entered になる) を指定できます。デフォルトは explicit all_entered です。
omp_taskwait イベント指定は、追跡されたスレッドが taskwait に入るか、出るタイミングです。state を指定でき、これは enter または exit になります。デフォルトは exit です。
omp_ordered イベント指定は、追跡されたスレッドが Ordered 領域に入るか、出るタイミングです。state を指定でき、これは begin、enter、または exit になります。デフォルトは enter です。
omp_critical イベント指定は、追跡されたスレッドがクリティカル領域に入るか、出るタイミングです。
omp_atomic イベント指定は、追跡されたスレッドが不可分領域に入るか、出るタイミングです。state を指定でき、これは begin または exit になります。デフォルトは begin です。
omp_flush イベント指定は、追跡されたスレッドが明示的なフラッシュ領域に入るか、出るタイミングです。
omp_task イベント指定は、追跡されたスレッドがタスク領域に入るか、出るタイミングです。state を指定でき、これは create、start、または finish になります。デフォルトは start です。
omp_master イベント指定は、追跡されたスレッドがマスター領域に入るか、出るタイミングです。
omp_single イベント指定は、追跡されたスレッドが Single 領域に入るタイミングです。
このセクションでは、その他のタイプのイベントのイベント指定について説明します。
attach イベントは、dbx がプロセスに正常に接続したタイミングです。
detach イベントは dbx がデバッグ中のプログラムから正常に切り離されたタイミングです。
lastrites イベントは、デバッグ中のプロセスが終了する直前のタイミングです。これは次の理由によって発生する可能性があります。
_exit(2) システムコールが、明示的な呼び出し経由か、または main() の戻り時に呼び出された。
終了シグナルが送信されようとするとき。
dbx コマンド kill によってプロセスが強制終了されつつあるとき。
プロセスの最終段階は、必ずではありませんが通常はこのイベントが発生したときに利用可能になり、プロセスの状態を確認することができます。このイベントのあとにプログラムの実行を再開すると、プロセスは終了します。
proc_gone イベントは dbx がデバッグ対象のプロセスに関連付けられなくなったときに発生します。事前定義済み変数 $reason は、signal、exit、kill、または detach になります。
prog_new イベントは、follow exec の結果として新しいプログラムがロードされたときに発生します。
stop イベントは、特に stop ハンドラへの応答として、ユーザーがプロンプトを受け取るなど、プロセスが停止するたびに発生します。次に例を示します。
display x when stop {print x;}
sync イベントは、デバッグ中のプロセスが exec() で実行された直後に発生します。a.out で指定されたメモリーはすべて有効で存在しますが、あらかじめ読み込まれるべき共有ライブラリはまだ読み込まれていません。たとえば printf は dbx に認識されていますが、まだメモリーにはマップされていません。
stop コマンドにこのイベントを指定しても期待した結果は得られません。when コマンドに指定してください。
syncrtld イベントは、sync、またはデバッグ中のプロセスがまだ共有ライブラリを処理していない場合は attach のあとに発生します。これは、動的リンカーの起動コードが実行され、プリロード済みのすべての共有ライブラリのシンボルテーブルがロードされたあと、ただし、.init セクション内のコードが実行される前に実行します。
stop コマンドにこのイベントを指定しても期待した結果は得られません。when コマンドに指定してください。
thr_create イベントは、スレッドまたは指定したスレッド ID を持つスレッドが作成されたときに発生します。たとえば、次の stop コマンドでスレッド ID t@1 はスレッド作成を示しますが、スレッド ID t@5 は作成済みスレッドを示しています。
stop thr_create t@5 -thread t@1
thr_exit イベントは、スレッドが終了したときに発生します。指定したスレッドの終了を取り込むには、次のように stop コマンドで -thread オプションを使用します。
stop thr_exit -thread t@5
timer イベントの構文:
timerseconds
timer イベントは、デバッグ中のプログラムが seconds 秒間実行されたときに発生します。このイベントで使用されるタイマーは、collector コマンドで共有されます。解像度はミリ秒であるため、秒の浮動小数点値 (0.001 など) が使用可能です。
イベント指定のため修飾子は、ハンドラの追加属性を設定します。もっとも一般的な種類はイベントフィルタです。修飾子はイベント指定のキーワードのあとに指定しなければなりません。修飾子はダッシュ ( -) から始まります。各修飾子の構成は次のとおりです。
-if 修飾子の構文:
-ifcondition
イベント仕様で指定されたイベントが発生したとき、条件が評価されます。イベントは、条件が非ゼロと評価された場合にだけ発生すると考えられます。
–if 修飾子が、in または at などの 1 つだけのソース位置が関連付けられたイベントで使用された場合、condition はその位置に対応するスコープで評価されます。そうでない場合は、必要なスコープによって正しく修飾する必要があります。
マクロ展開は、print コマンドと同じ規約に従った条件で実行されます。
–resumeone 修飾子は、マルチスレッドプログラムのイベント指定で、-if 修飾子とともに使用して、条件に関数呼び出しが含まれている場合に 1 つのスレッドのみを再開させることができます。詳細については、条件付きフィルタによるブレークポイントの修飾を参照してください。
-in 修飾子の構文:
-infunction
イベントは指定した関数の最初の命令に達したときから、関数が戻るときまでの間に発生した場合にのみトリガーします。関数の再帰は無視されます。
-count 修飾子の構文:
-countn
または
-count infinity
–count n および -count infinity 修飾子は、0 からのハンドラカウントを持ちます (イベントカウンタの使用を参照)。イベントが発生するたび、n に達するまでカウントはインクリメントします。一度それが生じると、ハンドラはファイアし、カウンタはゼロにリセットされます。
プログラムが実行または再実行されると、すべてのイベントのカウントがリセットされます。より具体的に言えば、カウントは sync イベントが発生するとリセットされます。
カウントは debug –r コマンド (debug コマンドを参照) または attach –r コマンド (attach コマンドを参照) を使用して新しいプログラムのデバッグを開始したときにリセットされます。
-temp 修飾子は一時ハンドラを作成します。イベントが発生すると、一時イベントは削除されます。デフォルトではハンドラは、一時イベントではありません。ハンドラが計数ハンドラ (-count が指定されたイベント) の場合はゼロに達すると自動的に破棄されます。
一時ハンドラをすべて削除するには delete -temp を実行します。
-instr 修飾子はハンドラを命令レベルで動作させます。これにより、ほとんどの ' i' で始まるコマンドは不要となります。この修飾子は、イベントハンドラの 2 つの面を修飾します。
出力されるどのメッセージもソースレベルの情報ではなく、アセンブリレベルを示す。
イベントの細分性が命令レベルになる。たとえば step –instr は、命令レベルのステップ実行を意味する。
-thread 修飾子の構文:
-threadthread-ID
-thread 修飾子はイベントを発生させたスレッドが異なるスレッド ID に一致する場合にのみ、アクションが実行されることを意味します。プログラムが次から次に実行されるうちに、目的とする特定のスレッドに、異なるスレッド ID が割り当てられることがあります。
-lwp 修飾子の構文:
-lwplwp-ID
-lwp 修飾子はイベントを発生させたスレッドが lwp-ID に一致する場合にのみ、アクションが実行されることを意味します。イベントを発生させたスレッドが lwp-ID と一致する場合にのみ、アクションが実行されます。プログラムが次から次に実行されるうちに、目的とする特定のスレッドに、異なる lwp-ID が割り当てられることがあります。
-hidden 修飾子は 通常の status コマンドでハンドラを非表示にします。隠されたハンドラを表示するには、status –h を使用してください。
通常、すべてのハンドラは、新しいプログラムが読み込まれると廃棄されます。–perm 修飾子を使用すると、デバッグセッション間でハンドラが維持されます。delete コマンド単独では、永続ハンドラは削除されません。永続ハンドラを削除するには、delete –p を使用してください。
イベント指定と修飾子のための構文はキーワードドリブンで、ksh 規則に基づきます。すべてのものがスペースで区切られた単語に分割されます。
下位互換性のため、式の中には空白を含むことができます。そのため、式の内容があいまいになることがあります。たとえば、次の 2 つのコマンドがあるとします。
when a -temp when a-temp
最初の例では、アプリケーションで temp という名前の変数が使用されていても、dbx 構文解析プログラムは –temp を修飾子としてイベント指定を解釈します。下の例では、a-temp がまとめて言語固有の式解析プログラムに渡され、a および temp という変数がない場合、エラーが発生します。オプションを括弧で囲むことにより、解析を強制できます。
特定の読み取り専用の ksh 事前定義済み変数が用意されています。次の表に示す変数は常に有効です。
|
次の例に、whereami を実装できることを示します。
function whereami { echo Stopped in $func at line $lineno in file $(basename $file) echo "$lineno\t$line" }
このセクションで説明する変数は、when コマンド本体内でのみ有効です。
本体の実行中、$handlerid は本体が属する when コマンドの ID です。次のコマンドは同等です。
when X -temp { do_stuff; } when X { do_stuff; delete $handlerid; }
特定の変数は、以下の表に示すように、when コマンドの本体内および特定のイベントに対してのみ有効です。
|
|
|
|
|
|
|
このセクションでは、イベントハンドラの設定のいくつかの例を挙げます。
この例は、array[99] にデータ変更ブレークポイントを設定する方法を示しています。
(dbx) stop access w &array[99] (2) stop access w &array[99], 4 (dbx) run Running: watch.x2 watchpoint array[99] (0x2ca88[4]) at line 22 in file "watch.c" 22 array[i] = i;
(dbx) when step { echo at line $lineno; }
次の例に、関数内にいる間ハンドラを有効にする方法を示します。
<dbx> trace step -in foo
このコマンドは次と同等です。
# create handler in disabled state when step -disable { echo Stepped to $line; } t=$newhandlerid # remember handler id when in foo { # when entered foo enable the trace handler -enable "$t" # arrange so that upon returning from foo, # the trace is disabled. when returns { handler -disable "$t"; }; }
この例は、小さなプログラムで実行された行数を確認する方法を示しています。入力:
(dbx) stop step -count infinity # step and stop when count=inf (2) stop step -count 0/infinity (dbx) run ... (dbx) status (2) stop step -count 133/infinity
プログラムは停止することなく、プログラムが終了します。実行された行の数は 133 です。このプロセスは非常に低速です。この方法が有効なのは、何度も呼び出される関数にブレークポイントを設定している場合です。
この例は、コードのある行で実行する命令数をカウントする方法を示しています。
(dbx) ... # get to the line in question (dbx) stop step -instr -count infinity (dbx) step ... (dbx) status (3) stop step -count 48/infinity # 48 instructions were executed
ステップ実行している行で関数呼び出しが行われる場合、最終的にそれらの呼び出しもカウントされます。step イベントの代わりに next イベントを使用すれば、そのような呼び出しはカウントされません。
別のイベントが発生した場合のみ、ブレークポイントを有効にします。たとえば、プログラムが関数 hash で、ただし 1300 番目のシンボル検索の後にのみ、正しく実行しなくなった場合、次のブレークポイントを使用します。
(dbx) when in lookup -count 1300 { stop in hash hash_bpt=$newhandlerid when proc_gone -temp { delete $hash_bpt; } }
この例では、アプリケーションで replay 時にリセットされる必要があるファイルを処理する場合、プログラムを実行するたびにこれを行うハンドラを書くことができます。
(dbx) when sync { sh regen ./database; } (dbx) run < ./database... # during which database gets clobbered (dbx) save ... # implies a RUN, which implies the SYNC event which (dbx) restore # causes regen to run
この例は、プログラムの実行中にプログラムの場所をすばやく確認する方法を示しています。入力:
(dbx) ignore sigint (dbx) when sig sigint { where; cancel; }
次に、^C を発行して、プログラムを停止しないでそのスタックトレースを調べます。
この例は、基本的にコレクタ側の標本モードで実行することです (これだけではありません)。^C が使われているため、プログラムに割り込むには SIGQUIT (^\) を使用します。
次の例に、IEEE アンダーフローなど、特定の浮動小数点例外のみを捕獲する方法を示します。
(dbx) ignore FPE # disable default handler (dbx) help signals | grep FPE # can’t remember the subcode name ... (dbx) stop sig fpe FPE_FLTUND ...
ieee ハンドラを有効にする詳細については、FPE シグナルのトラップ (Oracle Solaris のみ)を参照してください。