イベント指示子は、stop, when および trace コマンドが型やパラメータを表すために使用します。その書式はイベントタイプを示すキーワードと省略可能なパラメータです。
次に、イベント仕様、構文、および説明を示します。
関数 func に制御が移って、その先頭の行が実行される直前。-instr モードの場合は、関数の最初の命令が実行される直前です。in func を -in func と混同しないでください。func には仮パラメータを含むことができるため、多重定義された関数名、またはテンプレート・インスタンスの指定に役立ちます。たとえば、次のように使用できます。
stop in mumble(int, float, struct Node *)
特定の行 lineno が実行される直前。filename を指定した場合は、そのファイルの特定の行が実行される直前。ファイル名には、ソースファイル名またはオブジェクトファイル名を指定します。引用符マークは不要ですが、ファイル名に不正な文字が含まれる場合には必要なことがあります。
at filename:lineno
特定の行 lineno がテンプレートコードに含まれる場合は、そのテンプレートのすべてのインスタンスに 1 バイト挿入されます。
func という名前の多重定義関数のすべて、またはテンプレートインスタンスのすべてに対し、in func と同じ働きをします。
すべてのクラスの func という名前のメンバー関数に対し、in func と同じ働きをします。
クラス classname のメンバーであるすべてのメンバー関数に対し、in func と同じ働きをします。
obj-expr に指定されているアドレスのオブジェクトを呼び出したメンバー関数が呼び出されているとき。
variable の値が変化するとイベントが発生します。
cond-expr によって示される条件が真と評価されます。cond-expr には任意の式を使用できますが、整数型に評価されなければなりません。
このイベントは、現在表示されている関数の戻りのブレークポイントです。表示されている関数を使用するのは、いくつかの up を行なった後に returns イベント指定を使用できるようにするためです。通常の戻りイベントは常に一時イベント (-temp) で、動作中のプロセスが存在する場合にだけ作成できます。
これは一時イベントではありません。特定の関数がその呼び出し場所にリターンするたびに発生します。戻り値は示されませんが、SPARC プラットフォームでは $o0、Intel プラットフォームでは $eax を使用して、必須戻り値を調べることができます。
SPARC |
$o0 |
Intel |
$eax |
when in func { stop returns; }
step イベントは、ソース行の先頭の命令が実行されると発生します。たとえば、次のようにシンプルに表現することができます。
when step { echo $lineno: $line; }
step を有効にするということは、次に cont が使用されるときに自動的にステップ実行するように dbx に命令することと同じです。step コマンドは、次のように指定できます。
alias step="when step -temp { whereami; stop; }; cont"
step に似た働きをしますが、関数内をステップ実行しません。
デバッグの対象が seconds で指定された時間だけ実行されると発生します。これに使用されるタイマーは、collector コマンドと共有されます。分解能がミリ秒単位であるため、秒数に浮動小数点値を使用することができます。
指定したシグナルが子プロセスに初めて送信された場合に、このイベントが起動します。sig は、10 進数または大文字か小文字のシグナル名で表すことができます。また、シグナル名には接頭辞“SIG”をつけても構いません。これは、catch/ignore コマンドから完全に独立しています。もっとも、catch コマンドは次のようにしても実現できます。
function simple_catch { when sig $1 { stop; echo Stopped due to $sigstr $sig whereami } }
sig イベントを受け取っても、プロセスはまだ生きています。シグナルの送られるプロセスを cont した場合にだけ、シグナルはプロセスに配信されます。
このイベントは、指定されたサブコード sub-code を持つ指定されたシグナル sig が子プロセスに最初に送信されたときに起動します。シグナルの場合と同じように、サブコードも 10 進数、大文字または小文字の名前 (接頭辞は省略可能) のいずれかで入力できます。
このイベントは、指定されたフォールト (障害) fault が発生したときに起動します。フォールトはアーキテクチャに依存しますが、dbx は proc(4) で定義された次のフォールトを認識しています。
FLTILL |
不正命令 |
FLTPRIV |
特権つき命令 |
FLTBPT* |
ブレークポイント命令 |
FLTTRACE* |
トレーストラップ (ステップ実行) |
FLTACCESS |
メモリーアクセス (境界合わせなど) |
FLTBOUNDS* |
メモリー境界 (無効なアドレス) |
FLTIOVF |
整数オーバーフロー |
FLTIZDIV |
整数ゼロ除算 |
FLTPE |
浮動小数点例外 |
FLTSTACK |
修復不可能なスタックフォールト |
FLTPAGE |
修復可能なページフォールト |
* BPT、TRACE、BOUNDS は、ブレークポイント、単一ステップ実行、ウォッチポイントを設定するために dbx で使用されるため注意が必要です。これらのコマンドを操作すると、dbx の内部処理に支障をきたす場合があります。
これらのフォールトは、/sys/fault.h から抜粋されています。fault には上記の名前を大文字または小文字で指定できるほか、実際のコードも指定できます。また、コードの名前には、接頭辞 FLT- をつけることがあります。
addr-exp で指定されたメモリーがアクセスされたとき。
mode には、メモリーがアクセスされたことを示す、次のいずれか (またはすべて) の文字を指定します。
r |
メモリーが読み取られた |
w |
メモリーが書き込まれた |
x |
メモリーが実行された |
さらに mode には、次のいずれかの文字も指定することができます。
a |
アクセス後にプロセスを停止する (デフォルト) |
b |
アクセス前にプロセスを停止する |
いずれの場合も、プログラムカウンタは副作用アクションの前後で違反している命令をポイントします。
access は modify の代替イベントです。どちらの構文も、Solaris 2.4、2.5、2.5.2、2.6、7 で動作します。ただし、そのうち Solaris 2.6 を除くオペレーティング環境では、modify と同じ制限が課せられ、wa モードしか使用できません。
同じ範囲を重複使用することはできません。
指定されたアドレス範囲で変更があったとき。これは古いウォッチポイント機能です。
addr-exp は、その評価によりアドレスを生成できる任意の式です。シンボル式を使用すると、監視対象の領域のサイズが自動的に推定されます。このサイズは ',' 構文を使用して変更できます。また、記号を使用しない、型を持たないアドレス式を使用することもできますが、その場合はサイズを指定する必要があります。たとえば、次のようにします。
stop modify 0x5678, sizeof(Complex)
スタック上のアドレスを監視することはできません。
監視中のアドレスがシステムコールによって変更されても、イベントは起動しません。
共有メモリー (MAP_SHARED) は監視できません。dbx が共有メモリーに格納されたほかのプロセスを捕捉できないためです。また、dbx は SPARC の swap 命令と ldstub 命令を適切に処理できません。
指定されたシステムコールが起動された直後で、プロセスがカーネルモードに入ったとき。
dbx の認識するシステムコールは procfs(4) の認識するものに限られます。これらのシステムコールはカーネルでトラップされ、/usr/include/sys/syscall.h に列挙されます。
これは、ABI の言うところのシステムコールとは違います。ABI のシステムコールの一部は部分的にユーザーモードで実装され、非 ABI のカーネルトラップを使用します。ただし、一般的なシステムコールのほとんど (シグナル関係は除く) は syscall.h と ABI で共通です。
指定されたシステムコールが終了し、プロセスがユーザーモードに戻る直前。
引数がないときは、すべてのシステムコールがトレースされます。ここで、modify イベントや RTC (実行時検査) などの特定の dbx は、子プロセスにその目的でシステムコールを引き起こすことがあることに注意してください。トレースした場合にそのシステムコールの内容が示されることがあります。
follow exec の結果新しいプログラムが読み込まれると始まります。
このイベントのハンドラは常に永続です。
プロセスが停止したとき。特に stop ハンドラによりユーザーがプロンプトを受け取るときのようにプロセスが停止すると、このイベントが起動します。次に例を示します。
display x when stop {print x;}
デバッグ対象のプロセスが exec() で実行された直後。a.out で指定されたメモリーはすべて有効で存在しますが、あらかじめ読み込まれるべき共有ライブラリはまだ読み込まれていません。たとえば printf は dbx に認識されていますが、まだメモリーにはマップされていません。
stop コマンドにこのイベントを指定しても期待した結果は得られません。when コマンドに指定してください。
このイベントは、sync (被デバッグ側が共有ライブラリをまだ処理していない場合は attach) の後に発生します。すなわち、動的リンカーの起動時コードが実行され、あらかじめ読み込まれている共有ライブラリすべてのシンボルテーブルが読み込まれた後、ただし、.init セクション内のコードがすべて実行される前に発生します。
stop コマンドにこのイベントを指定しても期待した結果は得られません。when コマンドに指定してください。
dbx がプロセスを正常に接続した直後。
dbx がプロセスを切り離す直前。
lwp が終了したとき。$lwp には、終了した LWP の ID が含まれます。
dbx がデバッグ中のプロセスと関連しなくなるとき。事前定義済み変数 $reason に、signal、exit、kill、または detach のいずれかが設定されます。
デバッグ対象のプロセスが終了する直前。このイベントが発生するのは次の 3 つの場合です。
システムコール _exit (2) が呼び出し中 (これは、明示的に呼び出されたとき、または main() のリターン時に発生します)。
終了シグナルが送信されようとするとき。
dbx コマンド kill によってプロセスが強制終了されつつあるとき。
これらのイベントは、dlopen() または dlclose() の呼び出しが正常終了した後に発生します。dlopen() または dlclose() の呼び出しにより、複数のライブラリが読み込まれることがあります。これらのライブラリのリストは、事前定義済み変数 $dllist で常に入手できます。$dllist の中の最初の単語は実際には "+" または "-" で、それぞれライブラリが追加されているか、削除されているかを示します。
lib-path は、該当する共有ライブラリの名前です。これを指定した場合、そのライブラリが読み込まれたり、読み込みが取り消されたりした場合にだけイベントが起動します。その場合、$dlobj にライブラリの名前が格納されます。また、$dllist も利用できます。
lib-path が / で始まる場合は、パス名全体が比較されます。それ以外の場合は、パス名のベースだけが比較されます。
lib-path を指定しない場合、イベントは任意の dl 動作があるときに必ず起動します。$dlobj は空になりますが、$dllist は有効です。
イベント指定のため修飾子は、ハンドラの追加属性を設定します。最も一般的な種類はイベントフィルタです。修飾子はイベント指定のキーワードの後に指定しなければなりません。修飾語はすべて '-' で始まります (その前にブランクが置かれます)。各修飾子の構成は次のとおりです。
event-spec で指定されたイベントが発生したとき、条件 cond が評価されます。イベントは、条件が非ゼロと評価された場合にだけ発生すると考えられます。条件は、フィルタと呼ばれることがあります。フィルタを使用したハンドラをフィルタ化ハンドラと呼びます。
-if が、in または at などの単独のソース位置に基づくイベントで使用された場合、cond はその位置に対応するスコープで評価されます。そうでない場合は、必要なスコープによって正しく修飾する必要があります。
ハンドラは、指定した関数 func、または func から呼び出された関数によって制御されている間だけ有効になります。関数へ入った回数は、再帰呼び出しに正しく対応するため「参照による計数」が行われます。修飾語 -in によって修飾されたハンドラは、「func によって範囲が制限されている」といいます。
無効な状態にしてイベントを作成します。
イベントをゼロからカウントします。count はその値が n に達するまで、イベントが発生するたびにインクリメントされます。カウントが n に達すると、イベントが起動し、カウンタがゼロにリセットされます。
プログラムが実行または再実行されると、すべてのイベントのカウントがリセットされます。より具体的に言えば、カウントは sync イベントが発生するとリセットされます。
一時ハンドラを作成します。イベントが発生すると、一時イベントは削除されます。デフォルトではハンドラは、一時イベントではありません。ハンドラが計数ハンドラ (-count が指定されたイベント) の場合はゼロに達すると自動的に破棄されます。
一時ハンドラをすべて削除するには delete -temp を実行します。
イベントを命令レベルで動作させます。これにより、ほとんどの 'i' で始まるコマンドは不要となります。この修飾子は、イベントハンドラの 2 つの面を修飾します。
出力されるどのメッセージもソースレベルの情報ではなく、アセンブリレベルを示す。
イベントの細分性が命令レベルになる。たとえば step -instr は、命令レベルのステップ実行を意味する。
指定されたイベントがスレッド識別子 tid に一致するアクティブなスレッドで発生した場合にコマンドを実行します。
指定されたイベントが LWP 識別子 lid に一致するアクティブな LWP で発生した場合にコマンドを実行します。
ハンドラが正規の status コマンドに示されないようにします。隠されたハンドラを表示するには、status -h を使用してください。
通常、すべてのハンドラは、新しいプログラムが読み込まれると廃棄されます。この修飾子を使用すると、ハンドラはデバッグが終わっても保存されます。delete コマンド単独では、永続ハンドラは削除されません。永続ハンドラを削除するには、delete -p を使用してください。