dtraceプロバイダ
dtraceプロバイダには、DTrace自体に固有のプローブが含まれています。
これらのプローブを使用して、トレースの開始前に状態を初期化し、トレースの完了後にその状態を処理して、他のプローブでの予期しない実行エラーを処理できます。
BEGINプローブ
BEGINプローブは、他のどのプローブより先に起動します。
すべてのBEGIN節が完了するまで、他のプローブは起動しません。 このプローブを使用すると、他のプローブで必要なすべての状態を初期化できます。 次の例は、BEGINプローブを使用して、mmap()の保護ビットとテキスト表現の間をマップする連想配列の初期化を示しています:
dtrace:::BEGIN
{
prot[0] = "---";
prot[1] = "r--";
prot[2] = "-w-";
prot[3] = "rw-";
prot[4] = "--x";
prot[5] = "r-x";
prot[6] = "-wx";
prot[7] = "rwx";
}
syscall::mmap:entry
{
printf("mmap with prot = %s", prot[arg2 & 0x7]);
}
BEGINプローブは、未指定のコンテキストで起動します。つまり、stackやustackの出力と、コンテキスト固有の変数(execnameなど)の値はすべて任意です。 これらの値に依存したり、これらの値を有意な情報として解釈しないようにしてください。 BEGINプローブに、引数は定義されていません。
ENDプローブ
ENDプローブは、他のどのプローブより後に起動します。
このプローブは、他のプローブ節がすべて完了するまで起動しません。 このプローブを使用すると、収集された状態の処理や、出力のフォーマットが可能です。 そのため、ENDプローブではprinta関数が多用されます。 次のように、BEGINプローブとENDプローブを併用すると、トレースにかかった合計時間を測定できます:
dtrace:::BEGIN
{
start = timestamp;
}
/*
* ... other tracing functions...
*/
dtrace:::END
{
printf("total time: %d secs", (timestamp - start) / 1000000000);
}
BEGINプローブと同じく、ENDプローブにも引数は定義されていません。 ENDプローブが起動するコンテキストは任意であるため、これには依存できません。
ノート:
exit関数は、トレースを停止してENDプローブを起動させます。 ただし、exit関数が呼び出されてからENDプローブが起動するまでには遅延が発生します。 この遅延の間、それ以上のプローブは起動できません。 プローブがexit関数を呼び出した後、exitがコールされたことをDTraceコンシューマが判断してトレースを停止するまで、ENDプローブは起動しません。 exitのステータスをチェックする間隔は、statusrateオプションで設定できます。
ERRORプローブ
ERRORプローブは、DTraceプローブの節の処理中にランタイム・エラーが発生すると起動します。
ランタイム・エラーが発生した場合、DTraceはエラーが発生した節の残りの部分を処理しません。 スクリプトにERRORプローブが含まれている場合は、そのプローブがすぐにトリガーされます。 ERRORプローブの処理後に、トレースが続行されます。 Dランタイム・エラー以降のすべてのトレースを停止する場合は、ERRORプローブの節にexit()アクションを含める必要があります。
次の例では、節によるNULLポインタの間接参照が試行され、それによりERRORプローブが起動します。 error.dという名前のファイルに保存します。
dtrace:::BEGIN
{
*(char *)NULL;
}
dtrace:::ERROR
{
printf("Hit an error!");
}
このプログラムを実行すると、次のような出力が表示されます。
dtrace: script 'error.d' matched 2 probes
dtrace: error on enabled probe ID 3 (ID 1: dtrace:::BEGIN): invalid address (0x0) in action #1 at BPF pc 142
CPU ID FUNCTION:NAME
0 3 :ERROR Hit an error!
出力は、ERRORプローブが起動したことと、dtraceがエラーをレポートしたことを示します。dtraceは独自の方法でERRORプローブを有効にし、エラーのレポートを可能にします。 ERRORプローブを使用すると、カスタムのエラー処理を作成できます。
次の表では、ERRORプローブの引数について説明します。
| 引数 | 説明 |
|---|---|
|
|
エラーの原因となったプローブで有効化されたプローブID (EPID) |
|
|
フォルトの原因となったアクションのインデックス |
|
|
そのアクションへのDIFオフセット(該当しない場合は-1) |
|
|
フォルト・タイプ。 |
|
|
フォルト・タイプに固有の値。 |
次の表に、arg4で指定できる様々なフォルト・タイプと、各フォルト・タイプに対してarg5がとる値を示します。
| arg4の値 | 説明 | arg5の意味 |
|---|---|---|
|
|
不明なフォルト・タイプ |
なし |
|
|
マップされていないアドレスまたは無効なアドレスへのアクセス |
アクセスされるアドレス |
|
|
境界違反のメモリー・アクセス |
アクセスされるアドレス |
|
|
不正または無効な操作 |
なし |
|
|
整数のゼロ除算 |
なし |
|
|
スクラッチ割当てに対応できるスクラッチ・メモリーの不足 |
なし |
|
|
カーネル・アドレスまたはプロパティのアクセスが試行されたが、十分な権限がない |
アクセスされるアドレス(該当しない場合は0) |
|
|
ユーザー・アドレスまたはプロパティのアクセスが試行されたが、十分な権限がない |
アクセスされるアドレス(該当しない場合は0) |
|
|
DTrace内部パラメータのタプル・スタック・オーバーフロー |
なし |
|
|
ユーザー・プロセス・スタックが無効 |
無効なスタック・ポインタのアドレス |
DTRACEFLT_BADSIZE
|
無効なサイズのエラー。alloca()、bcopy()、copyin()などの関数に無効なサイズが渡された時に発生します。
|
無効なサイズ。 |
DTRACEFLT_BADINDEX
|
スカラー配列の範囲外の索引。 | 指定された索引。 |
DTRACEFLT_LIBRARY
|
ライブラリ・レベルのエラー | なし。 |
ERRORプローブで実行されたアクションがエラーの原因になっている場合、そのエラーはメッセージなしに削除されます。 ERRORプローブは、再帰的に呼び出されません。