目次
DTraceここはマニュアル抜粋のメモ。あとで使うなとおもった内容を一式抜粋してます。 ページ数がある場合は、日本語マニュアルのページ数になってます。
samples文法とかはマニュアル読めって感じで、例によって自分で使ったのを載せる方向で。
プロセスのuserland symbol trace以下のコマンドが基本型。ユーザシンボルのtraceであり、対象execnameに含まれるシンボルだけが trace出力の対象になる。このため、runtime libraryの呼び出し等も含めたい場合、probeの probemodule(左から2項目)の指定を適切に変える必要がある。(-qを指定すると出力がぐちゃぐちゃに なるので注意。)dtrace -c "<execname> <args>" -F -n 'pid$target:<execname>::entry, pid$target:<execname>::return' user symbolの関数の場合でも :::enterのarg[0-9]はその関数の引数になっているので、内容のdumpが可能である。
子プロセスのexec/waitpidモニタprocプロバイダでfork1付近をモニタしてみた。第1引数で対象とするexecnameを指定すると、 それがfork/execする子プロセスの生成付近をみて、終了時にsi_codeを拾ってログ出力する。で、びみょぃのが、procプロバイダのexec/exec-xxx probeのマニュアル上の説明では exec probeはfork前のstate、exec-xxx probeではfork後のstateを持つと書いてあるのだが、 実際に書いて調べてみる限りではexec probeが呼ばれた時点で子プロセスのstateになっていた。 #!/usr/sbin/dtrace -qs /* probe args[0] args[1] args[2] create psinfo_t * exec char * exec-failure int exit int fault int siginfo_t * start */ dtrace:::BEGIN { ename = $$1; printf("target execname : %s\n", ename); } this watchid; this chldname; proc:::exec / execname == ename / { watchid = curpsinfo->pr_ppid; chldname = args[0]; } proc:::exec-success / ppid == watchid / { flag[watchid] = 1; } proc:::exec-failure / ppid == watchid / { flag[watchid] = 0; } proc:::exit / ppid == watchid && flag[watchid] == 1 / { printf("[invoked by %d] %s si_code is %d\n", ppid, chldname, args[0]); }proc:::exitのhookは未完成。 ホントはwaitpid()とかで拾える子プロセスの戻り値を拾いたいのだが、 syscall::wait:がwaitid(2)とかwaitpid(3C)あたりなのかよくわからん。 それでも上記のサンプルを載せたのはproc providerの説明と実際が一致してなかったからだったりする。
syscall monitor他に方法もあるだろうが、引数に対応するsyscall::[func]:entryをmonitorするスクリプト。 引数を取って使うと言う部分のために載せてみた。#!/usr/sbin/dtrace -qs self string t; dtrace:::BEGIN { t = $$1; printf("target : %s\n",t); } syscall:::entry / probefunc == t / { printf("[%d]%s %s\n",pid, execname, t); printf("--------------\n"); }
file io monitorアプリケーションの動作を調べる上で、特定ファイルに対するI/Oが発生した際の ustackが 見たかったので書いてみた。対象とするファイルをコマンドライン引数で指定する。 io providerのargs[0]からioを、args[2]からファイルの情報を拾っている。なお、args[2]->fi_nameはパス名ではなく、ディレクトリエントリ上に登録されている ファイル名になるので、パス名だとmatchしないので注意。 io:::start / args[2]->fi_name == $1 / { printf("[%d]%s %s %s\n", pid, execname, args[0]->b_flags & B_READ ? "read" : "write", args[2]->fi_pathname); ustack(); printf("--------------\n"); }i/o providerの場合、ファイルをwriteするときはmonitorするのにreadするときは monitorできないのはなんでだろか。。。
syscall::open monitorこりゃ DTraceぃぃゎーと思ったきっかけになったのが下記。 これだとマニュアルに載ってる気がするが、記念品ってことでwopen(2)の第1引数がさすパス名文字列を、直だと当然ただの アドレスなので、copyinstr()で参照先をstringにして dumpしてる。 syscall::open:entry { printf("[%d]%s open %s\n", pid, execname, copyinstr(arg0)); ustack(); printf("--------------\n"); }
dtrace(1M)コマンドライン引数知りたいものだけを適当にメモ
DTraceマクロ変数一覧(p.183)抜粋の表のままです。
DTrace組込み変数一覧(p.67-)抜粋の表とは順番を適当に変えてます。
関連情報DTTOpenSolaris.orgのsub projectにDTrace Toolkitてのがある。 Solaris10の場合、/usr/demo/dtrace配下に、DTraceのマニュアルにあるスクリプトが一式入っているが、 マニュアルにあるものなので、実戦投入wはなかなかである。install用のscriptが同梱されている tar.gzが提供されていて、/opt/DTT配下に展開される。 2007-11-29現在で ver0.9.9である。 結構な数のD scriptがあるので、Solarisバンドル以外のサンプルとして見てみる価値があるし、 実際の調査でそのまま使える気がする。
公式にもリンクのあるこのサイトで、
DTTも含めたDTraceの紹介プレゼン(
misc雑多なリンク
Perl5.10.1 /w DTrace
|