Solaris 動的トレースガイド

入門ガイド

DTrace では、オペレーティングシステムカーネルとユーザープロセスに動的に変更を加え、「プローブ」と呼ばれる特定の場所に指定の追加データが記録されるようにすることで、ソフトウェアシステムの情報を得ることができます。プローブとは、DTrace が一連の「アクション」(スタックトレースの記録、タイムスタンプの記録、関数の引数の記録など) の実行要求を結合する場所またはアクティビティを指します。プローブは、Solaris システム内の要所要所に配置された、プログラミング可能な「センサー」として機能します。何が起こっているか確認したい場合は、DTrace を使って、該当する情報が適切なセンサーに記録されるようにプログラミングします。この結果、DTrace は、プローブが「起動」するたびにプローブからデータを収集し、ユーザーに報告します。プローブにアクションを指定しないと、DTrace はプローブの起動を記録するだけです。

DTrace のプローブには、2 つの名前があります。 1 つは一意の整数値の ID、もう 1 つは人間が読める形式の文字列名です。以下では、手始めに、新しいトレース要求を発行するたびに 1 回だけ起動するプローブ BEGIN を使って、ごく単純な要求を作成します。文字列名を指定してプローブを有効にするには、dtrace(1M) ユーティリティーの -n オプションを使用します。次のコマンドを入力します。


# dtrace -n BEGIN

しばらくすると、1 個のプローブが有効になったというメッセージに続いて、BEGIN プローブの起動を知らせる行が出力されます。この出力のあと、dtrace は、ほかのプローブの起動を待機して一時停止した状態になります。ここでは、ほかに有効なプローブがなく、BEGIN は 1 回しか起動しないため、Control-C キーを押して dtrace を終了し、シェルプロンプトに戻ってください。


# dtrace -n BEGIN
dtrace: description 'BEGIN' matched 1 probe
CPU     ID		      FUNCTION:NAME
  0      1                  :BEGIN
^C
#

この出力から BEGIN という名前のプローブが 1 回起動したことがわかり、その名前と整数値の ID (ここでは 1) が表示されています。デフォルトでは、このプローブが起動した CPU の整数名も出力されます。この例の CPU の欄を見ると、dtrace コマンドがプローブの起動時に CPU 0 で実行されていたことがわかります。

DTrace 要求の作成時には、任意の数のプローブおよびアクションを使用できます。以下では、上記のコマンド例に END プローブを追加して、2 つのプローブを使った単純な要求を作成してみましょう。END プローブは、トレースの完了時に 1 回だけ起動します。次のコマンドを入力し、BEGIN プローブの出力行が表示されたら、先ほどと同様に Control-C キーを押します。


# dtrace -n BEGIN -n END
dtrace: description 'BEGIN' matched 1 probe
dtrace: description 'END' matched 1 probe
CPU     ID		      FUNCTION:NAME
  0      1                  :BEGIN
^C
  0      2                    :END
#

Control-C キーを押すと、dtrace が終了し、END プローブが引き起こされます。dtrace は、END プローブの起動を報告してから終了します。

プローブを指定し、有効にする方法がわかったところで、今度は、おなじみの「Hello, World」プログラムの DTrace 版を作成してみましょう。DTrace 実行文は、コマンド行に入力するだけでなく、D プログラミング言語を使ってテキストファイルに記述することもできます。ここでは、テキストエディタで hello.d という名前の新しいファイルを作成し、以下の D プログラムを記述します。


例 1–1 hello.d: D プログラミング言語で記述した “Hello, World” プログラム

BEGIN
{
	trace("hello, world");
	exit(0);
}

プログラムを保存し、dtrace -s オプションを使って実行します。次のコマンドを入力します。


# dtrace -s hello.d
dtrace: script 'hello.d' matched 1 probe
CPU     ID		      FUNCTION:NAME
  0	    1                  :BEGIN   hello, world
#

先ほどの例と同様の出力に続いて、“hello, world” というテキストが出力されます。先ほどの例とは異なり、ここでは、しばらく待つ必要も Control-C キーを押す必要もありません。これは、hello.d ファイル内の BEGIN プローブに、「アクション」が指定されたからです。では、D プログラムの構造をもう少し掘り下げて、何が起こっているのか確認していきましょう。

D プログラムは、有効化の対象となるプローブ (複数可) について記述する複数の「」と、プローブの起動時に実行するアクションの集合 (オプション) で構成されます。アクションは、プローブ名に続く中括弧 ({ }) の中に、連続する文として列挙されます。各文の末尾には、セミコロン (;) が付きます。最初の文では、関数 trace() を使って、BEGIN プローブの起動時に指定の引数 (ここでは文字列「hello, world」を記録し、出力するように、DTrace に指示しています。2 番目の文では、関数 exit() を使って、トレースを中断し、dtrace コマンドを終了するように指示しています。DTrace は、trace()exit() のように、D プログラム内で呼び出せる便利な関数を提供しています。関数を呼び出すには、関数名に続いて、丸括弧内に引数を指定します。すべての D 関数については、第 10 章アクションとサブルーチンを参照してください。

C プログラミング言語の知識をお持ちのユーザーは、ここまでの例や名前から、DTrace の D プログラム言語が C に似ていることに気が付いていることでしょう。実は、D 言語は、C 言語のサブセットにトレース用の特殊な関数と変数を組み合わせた言語なのです。D 言語の機能の詳細については、第 2 章以降で学習します。以前に C プログラミングをしたことがあるなら、D 言語でトレースプログラムを作成するために、その知識をほぼそのまま流用できます。もちろん、C プログラミングの経験がなくても、D プログラミングは決して難しいものではありません。D プログラミングの全構文は、この章で学ぶことができます。言語の規則について学ぶ前に、まず DTrace の機能についてもう少し詳しく見ていきましょう。そのあとで上記より複雑な D プログラムの作成方法を学んでいきます。