次に、イベント仕様、構文、および説明を示します。
関数 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 は有効です。