DTrace ユーザーガイド

DTrace アクションの基本

DTrace は、アクションによって、DTrace フレームワーク外部のシステムと対話します。もっとも一般的なアクションは、DTrace バッファーへデータを記録するアクションです。そのほかに、現在のプロセスを停止するアクション、現在のプロセス内で特定のシグナルを発生させるアクション、トレースを中断するアクションなどがあります。システム状態を変更するアクションは、「破壊アクション」と見なされます。データ記録アクションは、デフォルトで、「主バッファー」にデータを記録します。主バッファーは、DTrace の呼び出し時に必ず使用されます。また、常に CPU 単位で割り当てられます。-cpu オプションを指定することにより、トレースとバッファーの割り当てを単一 CPU に制限できます。DTrace のバッファリングの詳細については、『Solaris 動的トレースガイド』の第 11 章「バッファーとバッファリング」 を参照してください。

ここからは、組み込み D 変数を使用する D 式の例を紹介していきます。次に示すのは、もっとも頻繁に使用する D 変数の一部です。

pid

現在のプロセス ID を表す変数。

execname

現在の実行可能ファイル名を表す変数。

timestamp

起動時からの経過時間をナノ秒単位で表す変数。

curthread

現在のスレッドを示す kthread_t 構造体へのポインタを表す変数。

probemod

現在のプローブのモジュール名を表す変数。

probefunc

現在のプローブの関数名を表す変数。

probename

現在のプローブの名前を表す変数。

D スクリプト言語のすべての組み込み変数については、「DTrace の組み込み変数」を参照してください。

D スクリプト言語には、特定のアクションを実行する組み込み関数も用意されています。すべての組み込み関数については、『Solaris 動的トレースガイド』の第 10 章「アクションとサブルーチン」を参照してください。trace() 関数は、D 式の結果をトレースバッファーに記録します。次に例を示します。

プローブに特定のアクションを実行させるときは、次の例のように、アクション名を {} 文字で囲んで指定します。


例 2–10 プローブのアクションを指定する


# dtrace -n 'readch {trace(pid)}'
dtrace: description 'readch ' matched 4 probes
CPU     ID                     FUNCTION:NAME
  0   4036                       read:readch          2040
  0   4036                       read:readch          2177
  0   4036                       read:readch          2177
  0   4036                       read:readch          2040
  0   4036                       read:readch          2181
  0   4036                       read:readch          2181
  0   4036                       read:readch             7
...

この例で要求されるアクションは、trace(pid) です。したがって、一番右の欄にプロセス ID 番号 (PID) が出力されています。



例 2–11 実行可能ファイル名をトレースする


# dtrace -m 'ufs {trace(execname)}'
dtrace: description 'ufs ' matched 889 probes
CPU     ID                     FUNCTION:NAME
  0  14977                  ufs_lookup:entry            ls
  0  15748                 ufs_iaccess:entry            ls
  0  15749                ufs_iaccess:return            ls
  0  14978                 ufs_lookup:return            ls
...
  0  15007                    ufs_seek:entry         utmpd
  0  15008                   ufs_seek:return         utmpd
  0  14963                   ufs_close:entry         utmpd
^C


例 2–12 システムコールの開始時刻をトレースする


# dtrace -n 'syscall:::entry {trace(timestamp)}'
dtrace: description 'syscall:::entry ' matched 226 probes
CPU     ID                     FUNCTION:NAME
  0    312                      portfs:entry    157088479572713
  0     98                       ioctl:entry    157088479637542
  0     98                       ioctl:entry    157088479674339
  0    234                   sysconfig:entry    157088479767243
...
  0     98                       ioctl:entry    157088481033225
  0     60                       fstat:entry    157088481050686
  0     60                       fstat:entry    157088481074680
^C


例 2–13 複数のアクションを指定する

複数のアクションを指定する場合は、各アクションを ; 文字で区切って指定します。


# dtrace -n 'zfod {trace(pid);trace(execname)}'
dtrace: description 'zfod ' matched 3 probes
CPU     ID                     FUNCTION:NAME
  0   4080                    anon_zero:zfod    2195   dtrace
  0   4080                    anon_zero:zfod    2195   dtrace
  0   4080                    anon_zero:zfod    2195   dtrace
  0   4080                    anon_zero:zfod    2195   dtrace
  0   4080                    anon_zero:zfod    2195   dtrace
  0   4080                    anon_zero:zfod    2197   bash
  0   4080                    anon_zero:zfod    2207   vi
  0   4080                    anon_zero:zfod    2207   vi
...

データ記録アクション

この節では、デフォルトで主バッファーにデータを記録するアクションを紹介します。これらのアクションを使って、投機バッファーにデータを記録することもできます。投機バッファーについては、「投機トレース」を参照してください。

trace() 関数

void trace(expression)

もっとも基本的なアクションは、D 式 expression を引数とし、指定バッファーに結果をトレースする trace() アクションです。

tracemem() 関数

void tracemem(address, size_t nbytes)

tracemem() アクションは、メモリー内のアドレスからバッファーにデータをコピーします。nbytes には、このアクションによってコピーされるバイト数を指定します。address には、コピーされるデータのアドレスを D 式で指定します。指定バッファーにコピーします。

printf() 関数

void printf(string format, ...) 

printf() アクションは、trace() アクションと同じように D 式をトレースします。ただし、printf() アクションでは、printf(3C) 関数と同様の方法で書式を制御できます。printf 関数の場合と同じく、パラメータは format 文字列と任意の数の引数です。デフォルトでは、これらの引数が指定バッファーにトレースされます。その後、指定された書式設定文字列に従って、これらの引数に dtrace コマンドの出力書式が設定されます。

printf() アクションの詳細については、『Solaris 動的トレースガイド』の第 12 章「出力書式」を参照してください。

printa() 関数

void printa(aggregation)
void printa(string format, aggregation)

printa() アクションでは、集積体に書式を設定して表示できます。集積体の詳細については、『Solaris 動的トレースガイド』の第 9 章「集積体」を参照してください。format 値を省略した場合、printa() アクションは DTrace コンシューマへの指令だけをトレースします。その指令を受け取ったコンシューマは、集積体をデフォルトの書式に編集して表示します。printa() の書式文字列については、『Solaris 動的トレースガイド』の第 12 章「出力書式」を参照してください。

stack() 関数

void stack(int nframes)
void stack(void)

stack() アクションは、カーネルスタックトレースを指定バッファーに記録します。nframes には、カーネルスタックの深さを指定します。nframes 値を省略した場合、stack() アクションは、stackframes オプションで指定された数のスタックフレームを記録します。

ustack() 関数

void ustack(int nframes, int strsize)
void ustack(int nframes)
void ustack(void)

ustack() アクションは、指定バッファーにユーザースタックトレースを記録します。nframes には、ユーザースタックの深さを指定します。nframes 値を省略した場合、ustack アクションは、ustackframes オプションで指定された数のスタックフレームを記録します。ustack() アクションは、プローブが起動するときに、呼び出しフレームのアドレスを特定します。スタックフレームは、DTrace コンシューマがユーザーレベルで ustack() アクションを処理したときに、シンボルに翻訳されます。strsize にゼロ以外の値を指定した場合、ustack() アクションは指定された容量の文字列空間を割り当て、これを使ってカーネルから直接、アドレスからシンボルへの翻訳を行います。

jstack() 関数

void jstack(int nframes, int strsize)
void jstack(int nframes)
void jstack(void)

jstack() アクションは、ustack() アクションの別名で、スタックフレーム数については jstackframes オプションに指定されている値を使用します。jstackアクションは、jstackstrsize オプションに指定された値を使って、文字列空間のサイズを決定します。デフォルトでは、jstacksize アクションはゼロ以外の値になります。

破壊アクション

破壊アクションを使用するためには、明示的な方法で有効にする必要があります。-w オプションを使用すれば、破壊アクションを有効にできます。破壊アクションを明示的に有効にしないまま、dtrace 内でその使用を試みると、dtrace は失敗し、次のようなメッセージが表示されます。

dtrace: failed to enable 'syscall': destructive actions not allowed

破壊アクションをはじめとする DTrace アクションについては、『Solaris 動的トレースガイド』の第 10 章「アクションとサブルーチン」を参照してください。

プロセス破壊アクション

一部の破壊アクションは、特定のプロセスだけに影響を及ぼします。こうしたアクションを実行できるのは、dtrace_proc 権限か dtrace_user 権限を持つユーザーだけです。DTrace のセキュリティー権限については、『Solaris 動的トレースガイド』の第 35 章「セキュリティ」を参照してください。

stop() 関数

プローブの起動によって stop() アクションが有効にされると、そのプローブを起動したプロセスはカーネルを出るときに停止します。このプロセスは、proc(4) アクションを使用してプロセスを停止したときと同じように停止します。

raise() 関数

void raise(int signal)

raise() アクションは、現在実行中のプロセスに、指定されたシグナルを送信します。

copyout() 関数

void copyout(void *buf, uintptr_t addr, size_t nbytes)

copyout() アクションは、バッファーからメモリー内のアドレスへデータをコピーします。nbytes には、このアクションによってコピーされるバイト数を指定します。buf には、データのコピー元バッファーを指定します。addr には、データのコピー先のアドレスを指定します。現在のスレッドに関連付けられたプロセスのアドレス空間内にあるアドレスを指定してください。

copyoutstr() 関数

void copyoutstr(string str, uintptr_t addr, size_t maxlen)

copyoutstr() アクションは、文字列をメモリー内のアドレスにコピーします。str には、コピーする文字列を指定します。addr には、文字列のコピー先のアドレスを指定します。現在のスレッドに関連付けられたプロセスのアドレス空間内にあるアドレスを指定してください。

system() 関数

void system(string program, ...) 

system() アクションは、program で指定されたプログラムを、シェルに入力として渡されたときのようにして実行します。

カーネル破壊アクション

システム全体に影響を及ぼす破壊アクションもあります。これらのアクションは慎重に使用してください。これらのアクションは、システムで実行中のすべてのプロセスに影響を及ぼします。さらに、そのシステムのネットワークサービスを使用しているその他のシステムに影響を及ぼすこともあります。

breakpoint() 関数

void breakpoint(void)

breakpoint() アクションは、カーネルブレークポイントを設定して、システムを停止し、カーネルデバッガに制御を移します。カーネルデバッガは、アクションを引き起こした DTrace プローブを表す文字列を発行します。

panic() 関数

void panic(void)

panic() アクションが指定されているプローブが起動すると、カーネルパニックが発生します。このアクションを実行すると、必要に応じて強制的にシステムのクラッシュダンプを出力できます。このアクションをリングバッファリングや事後分析と組み合わせることで、 システムの問題を診断できます。詳細は、『Solaris 動的トレースガイド』の第 11 章「バッファーとバッファリング」『Solaris 動的トレースガイド』の第 37 章「事後トレース」を参照してください。

chill() 関数

void chill(int nanoseconds)

chill() アクションが指定されているプローブが起動すると、指定された時間 (ナノ秒) だけ DTrace が実行され続けます。chill() アクションは、タイミング関連の問題の調査に役立ちます。DTrace プローブコンテキストでは、割り込みは無効になります。このため、chill() を使用すると、割り込み遅延、スケジュール遅延、ディスパッチ遅延が発生します。