dtraceコマンドは、「Dスクリプト」と呼ばれる言語によって記述されたスクリプト実行ができる。これにより、プローブからのデータ取り出しや、その集計が可能となるのだ。DスクリプトはC言語に近いスクリプト言語としての特徴を持っている。
ここでは簡単な例として、どのプログラムがファイルを何バイト読み書きしているのかを調べるスクリプトを作ってみる。
以下のリスト1に示すスクリプトをfileread.dというファイル名で保存する。
#!/usr/sbin/drace -s #pragma D option quiet syscall::read:return /arg0 > 0/ { @bytes[execname] = sum(arg0); } dtrace:::END { printa(@bytes); }
この時、次のように-sオプションを使うことで、このスクリプトを実行できる。
# dtrace -s fileread.d
実行しても、画面には何も表示されない。ここで、ほかの端末でcatコマンドやlessコマンド、moreコマンドなど、ファイルを読み取るコマンドをいくつか実行してみてほしい。その後、dtraceコマンドを実行した端末に戻って「Ctrl」+「C」キーを押すと、次のようにそれぞれのコマンドが読み取ったファイルの総バイト数が表示されるはずだ(表示される内容は環境によって異なる)。
# dtrace -s fileread.d ^C dtfile 43 tcsh 66 dtscreen 224 cat 1001 less 1644 more 1773 java 1950 dtwm 8589935310 sdtperfmeter 150323856509 Xorg 807453906948
リスト1の1行目は、シェルから直接実行できるようにするためのものであり必須ではない。このように記しておくと、このfileread.dに実行権限を付けておけば、「./fileread.d」とコマンド入力することで直接実行できるようになるという意味合いだ。
2行目はdtraceコマンドのオプション指定だ。「quiet」というオプションは、dtraceコマンドが余計な出力をしないようにすることを意味する。先に説明した「-n」オプションを指定した例では、プローブを使用するたびに、画面に、「0 19971 icmp_inbound:icmpInMsgs」といったメッセージが表示された。quitオプションを指定することにより、このような出力を抑制できるのだ。
Dスクリプトは、次のように、「プローブを通過したときに処理するブロックを羅列する」という構造になる。
プローブ名, プローブ名, …… / 条件式 / { 実行するスクリプト }
リスト1では、「syscall::read:return」と「dtrace:::END」の2つのプローブを処理している。
syscallプロバイダは、システムコールへの突入/退出時にイベントが発生するプローブだ。
突入時のプローブ名は「syscall::システムコール名:entry」、退出時のプローブ名は「syscall::システムコール名:return」という名前になる(Solaris Dynamic Tracing Guideの「Chapter 21 syscall Provider」を参照)。
詳細は省略するが、Solarisでは(というよりもUNIXでは)、ファイルを読み取る時にreadシステムコールを呼び出す。そこでリスト1では、「syscall::read:return」というプローブをフックして、readシステムコールを抜ける際、読み込んだバイト数の総和を求めるという処理をしている。
Copyright © ITmedia, Inc. All Rights Reserved.