DTrace プローブを複雑に組み合わせると、コマンド行での使用が難しくなる場合もあります。dtrace コマンドは、スクリプトをサポートしています。dtrace コマンドに -s オプションとスクリプトファイル名を指定することで、スクリプトを指定できます。実行可能な DTrace インタプリタファイルも作成できます。DTrace インタプリタファイルは、常に #!/usr/sbin/dtrace -s から始まります。
次のサンプルスクリプト syscall.d は、実行可能ファイルがシステムコールを開始するたびに、その実行可能ファイルの名前をトレースします。
syscall:::entry { trace(execname); }
ファイル名は接尾辞 .d で終わっています。D スクリプトの末尾は、通常、この形式になります。このスクリプトは、DTrace コマンド行から次のコマンドを使用して実行できます。
# dtrace -s syscall.d dtrace: description 'syscall ' matched 226 probes CPU ID FUNCTION:NAME 0 312 pollsys:entry java 0 98 ioctl:entry dtrace 0 98 ioctl:entry dtrace 0 234 sysconfig:entry dtrace 0 234 sysconfig:entry dtrace 0 168 sigaction:entry dtrace 0 168 sigaction:entry dtrace 0 98 ioctl:entry dtrace ^C |
このスクリプトは、次の 2 つの手順でコマンド行にファイル名を指定する方法で実行できます。まず、ファイルの先頭行がインタプリタの呼び出しになっていることを確認します。インタプリタの呼び出し行は、#!/usr/sbin/dtrace -s です。次に、ファイルの実行権を設定します。
# cat syscall.d #!/usr/sbin/dtrace -s syscall:::entry { trace(execname); } # chmod +x syscall.d # ls -l syscall.d -rwxr-xr-x 1 root other 62 May 12 11:30 syscall.d # ./syscall.d dtrace: script './syscall.d' matched 226 probes CPU ID FUNCTION:NAME 0 98 ioctl:entry dtrace 0 98 ioctl:entry dtrace 0 312 pollsys:entry java 0 312 pollsys:entry java 0 312 pollsys:entry java 0 98 ioctl:entry dtrace 0 98 ioctl:entry dtrace 0 234 sysconfig:entry dtrace 0 234 sysconfig:entry dtrace ^C |
D 言語はリテラル文字列をサポートします。DTrace の文字列は、NULL バイトで終了する文字配列として表現されます。文字列の可視部分は可変長で、NULL バイトの位置によって長さが決まります。DTrace は、各プローブが決まった量のデータをトレースするように、各文字列を固定サイズの配列に格納します。文字列の長さは、あらかじめ定義された文字列制限長を超えることはできません。この制限は D プログラム内で変更できます。dtrace コマンド行で strsize オプションをチューニングして変更することもできます。チューニング可能な DTrace オプションについては、『Solaris 動的トレースガイド』の第 16 章「オプションとチューニング可能パラメータ」を参照してください。デフォルトの制限長は 256 バイトです。
D 言語で文字列を参照するときは、char * 型ではなく、明示的な string 型を使用します。D リテラル文字列については、『Solaris 動的トレースガイド』の第 6 章「文字列」を参照してください。
# cat string.d #!/usr/sbin/dtrace -s fbt::bdev_strategy:entry { trace(execname); trace(" is initiating a disk I/O\n"); } |
このリテラル文字列の末尾の記号 \n によって、新規の行が生成されます。このスクリプトを実行するには、次のコマンドを入力します。
# dtrace -s string.d dtrace: script 'string.d' matched 1 probes CPU ID FUNCTION:NAME 0 9215 bdev_strategy:entry bash is initiating a disk I/O 0 9215 bdev_strategy:entry vi is initiating a disk I/O 0 9215 bdev_strategy:entry vi is initiating a disk I/O 0 9215 bdev_strategy:entry sched is initiating a disk I/O ^C |
dtrace コマンドを -q オプション付きで実行した場合、スクリプト内またはコマンド行呼び出しに明示的に指定されたアクションだけが記録されます。dtrace コマンドが通常生成するデフォルト出力は抑制されます。
# dtrace -q -s string.d ls is initiating a disk I/O cat is initiating a disk I/O fsflush is initiating a disk I/O vi is initiating a disk I/O ^C |
dtrace コマンドを使って、実行可能なインタプリタファイルを作成できます。このファイルには、実行権を設定する必要があります。ファイルの先頭行は、#!/usr/sbin/dtrace -s にする必要があります。この行には、dtrace コマンドのほかのオプションを指定できます。複数のオプションを指定する場合も、ダッシュ (-) は 1 つだけ入力してください。s オプションは、次の例のように、最後に指定してください。
#!/usr/sbin/dtrace -qvs |
dtrace コマンドのオプションを、D スクリプトの #pragma 行を使用して指定できます。次の D スクリプトの抜粋を参照してください。
# cat -n mem2.d 1 #!/usr/sbin/dtrace -s 2 3 #pragma D option quiet 4 #pragma D option verbose 5 6 vminfo::: ... |
次の表に、#pragma 行で使用できるオプション名を一覧します。
表 3–1 DTrace コンシューマオプション
オプション名 |
値 |
dtrace 別名 |
説明 |
---|---|---|---|
aggrate |
時間 |
集積体の読み取りレート |
|
aggsize |
サイズ |
集積体バッファーサイズ |
|
bufresize |
auto または manual |
バッファーのサイズ変更ポリシー |
|
bufsize |
サイズ |
-b |
主バッファーサイズ |
cleanrate |
時間 |
クリーンアップレート |
|
cpu |
スカラー |
-c |
トレースを有効にする CPU |
defaultargs |
— |
未知のマクロ引数の参照を許可する |
|
destructive |
— |
-w |
破壊アクションを許可する |
dynvarsize |
サイズ |
動的変数空間のサイズ |
|
flowindent |
— |
-F |
関数の開始 (entry) をインデントし、その前に -> を付ける。関数の終了 (return) のインデントを解除し、その前に <- を付ける |
grabanon |
— |
-a |
匿名状態を要求する |
jstackframes |
スカラー |
jstack() のデフォルトスタックフレームの数 |
|
jstackstrsize |
スカラー |
jstack() の文字列空間のデフォルトサイズ |
|
nspec |
スカラー |
投機の数 |
|
quiet |
— |
-q |
明示的にトレースされたデータだけを出力する |
specsize |
サイズ |
投機バッファーサイズ |
|
strsize |
サイズ |
文字列サイズ |
|
stackframes |
スカラー |
スタックフレームの数 |
|
stackindent |
スカラー |
stack() と ustack() の出力をインデントするときに使用する空白文字の数 |
|
statusrate |
時間 |
状態チェックレート |
|
switchrate |
時間 |
バッファー切り替えレート |
|
ustackframes |
スカラー |
ユーザースタックフレームの数 |
一連の組み込みマクロ変数も、D スクリプトで参照できます。これらのマクロ変数は、D コンパイラで定義されます。
マクロ引数
実効グループ ID
実効ユーザー ID
実グループ ID
プロセス ID
プロセスグループ ID
親プロセス ID
プロジェクト ID
セッション ID
ターゲットプロセス ID
タスク ID
実ユーザー ID
次の例では、D スクリプト syscalls2.d に、実行中の vi プロセスの PID が渡されます。vi コマンドが終了すると、D スクリプトも終了します。
# cat -n syscalls2.d 1 #!/usr/sbin/dtrace -qs 2 3 syscall:::entry 4 /pid == $1/ 5 { 6 @[probefunc] = count(); 7 } 8 syscall::rexit:entry 9 { 10 exit(0); 11 } # pgrep vi 2208 # ./syscalls2.d 2208 rexit 1 setpgrp 1 creat 1 getpid 1 open 1 lstat64 1 stat64 1 fdsync 1 unlink 1 close 1 alarm 1 lseek 1 sigaction 1 ioctl 1 read 1 write 1 |