7 DTraceの組込み変数リファレンス
DTraceには、Dプログラムやスクリプトで使用できる組込みスカラー変数のセットが含まれます。
マクロ変数
マクロ変数は、実行時に移入され、実行中のdtraceプロセスまたはコンパイラを実行しているプロセスに関する情報を識別する変数です。
Dコンパイラには、Dプログラムやインタプリタ・ファイルを記述するときに使用できる組込みマクロ変数のセットが定義されています。 マクロ変数は接頭辞としてドル記号($)が付く識別子であり、入力ファイルまたはスクリプトの処理時に、Dコンパイラによって1回展開されます。 次の表では、Dコンパイラに用意されているマクロ変数について説明します。
表7-1 Dマクロ変数
| 名前 | 説明 | 参照先 |
|---|---|---|
|
|
マクロ引数 |
「マクロ引数」を参照 |
|
|
実効グループID |
|
|
|
実効ユーザーID |
|
|
|
実グループID |
|
|
|
プロセスID |
|
|
|
プロセス・グループID |
|
|
|
親プロセスID |
|
|
|
セッションID |
|
|
|
ターゲット・プロセスID |
「ターゲット・プロセスID」を参照 |
|
|
実ユーザーID |
|
展開後の変数は、現在のdtraceプロセス、またはDコンパイラを実行しているプロセスに関連付けられた属性値になります。 すべてのマクロ変数は、プロセスIDやユーザーIDなどのシステム属性に対応する整数に展開されます。ただし、$[0-9]+マクロ引数と$targetマクロ変数はその例外です。
インタプリタ・ファイルでマクロ変数を使用すると、使用するたびに編集する必要のない永続的なDプログラムを作成できます。 たとえば、すべてのシステム・コール(dtraceコマンドで実行されるものを除く)をカウントするには、$pidを含む次のDプログラム節を使用します:
syscall:::entry
/pid != $pid/
{
@calls = count();
}
dtraceコマンドを呼び出すたびにプロセスIDは異なりますが、この節は常に想定どおりに動作します。 マクロ変数は、整数、識別子または文字列を使用できる場所であればどこでもDプログラムで使用できます。
マクロ変数は、入力ファイルまたはスクリプトの解析時に1回のみ、非再帰的に展開されます。
展開された各マクロ変数は、プローブ記述以外では、独立した入力トークンになり、これらを他のテキストと連結して1つのトークンにすることはできません。
たとえば、$pidが値456に展開される場合、次の例のDコードは、1つの整数トークン123456ではなく、2つの隣接するトークン123および456に展開され、構文エラーになります。
123$pid
ただし、プローブ記述では、マクロ変数は展開されて、隣接するテキストと連結されます。
マクロ変数は各プローブ記述フィールドで1回しか展開されないので、プローブ記述のデリミタ(:)を含めることはできません。
マクロ引数
Dコンパイラには、dtraceコマンド呼出しの一部として指定される追加の引数オペランドに対応する、一連のマクロ変数も用意されています。 これらのマクロ引数にアクセスするには、Dプログラム・ファイル名やdtraceコマンドは$0、最初の追加オペランドは$1、2番目の追加オペランドは$2など(以降同様)の組込み名を使用します。 -sオプションを指定した場合、$0はこのオプションで使用される入力ファイルの名前の値に展開されます。 Dプログラムをコマンドラインに指定した場合、$0は、dtraceコマンド自体の実行に使用するargv[0]の値に展開されます。
マクロ引数は、対応するテキストの形式に応じて、整数、識別子または文字列に展開されます。 すべてのマクロ変数と同じように、マクロ引数もDプログラムの整数、識別子、文字列トークンのかわりに使用できます。
次のすべての例では、適切なマクロ引数値を想定して有効なD式を形成できます:
execname == $1 /* with a string macro argument */
x += $1 /* with an integer macro argument */
trace(x->$1) /* with an identifier macro argument */
マクロ引数を使用すると、通常のLinuxコマンドと同様に実行されるDTraceインタプリタ・ファイルを作成し、ユーザーや他のツールによって指定された情報を使用して動作を変更できます。
たとえば次のDインタプリタ・ファイルは、特定のプロセスIDで実行され、tracewriteという名前のファイルに保存されるwrite()システム・コールをトレースします。
#!/usr/sbin/dtrace -s
syscall::write:entry
/pid == $1/
{
}
このインタプリタ・ファイルを実行可能ファイルにする場合は、コマンドライン引数をインタプリタ・ファイルの後に追加して、$1の値を指定できます。たとえば、次のようになります:
sudo chmod a+rx ./tracewrite
sudo ./tracewrite 12345
生成されるコマンド呼出しは、プロセスID 12345で実行される各write()システム・コールをカウントします。
Dプログラムが参照するマクロ引数がコマンドラインで指定されていない場合は、次の出力例に示すように、該当するエラー・メッセージが出力され、プログラムを正常にコンパイルできません:
dtrace: failed to compile script ./tracewrite: line 4:
macro argument $1 is not defined
defaultargsオプションを設定すると、Dプログラムで未指定のマクロ引数を参照できます。 defaultargsオプションを設定した場合、未指定の引数の値は0になります。 Dコンパイラ・オプションの詳細は、「DTrace実行時およびコンパイル時のオプション・リファレンス」を参照してください。 Dプログラムで参照されない別の引数をコマンドラインで指定した場合も、Dコンパイラはエラー・メッセージを生成します。
マクロ引数の値は、整数、識別子または文字列の形式に一致する必要があります。 引数がこれらの形式に一致しない場合、Dコンパイラは該当するエラー・メッセージを出力します。 DTraceインタプリタ・ファイルに文字列のマクロ引数を指定するときは、シェルで二重引用符や文字列の内容が解釈されないように、引数をさらに一対の一重引用符で囲みます:
sudo ./foo '"a string argument"'
Dのマクロ引数が整数または識別子の形式に一致する場合でも、あえて文字列トークンとして解釈させる場合は、マクロ変数またはマクロ引数の名前の前に、ドル記号を2つ追加します(たとえば、$$1)。こうすれば、Dコンパイラはこの引数の値を二重引用符で囲まれた文字列とみなすようになります。 「表4-6」ごとの通常のD文字列エスケープ・シーケンスはすべて、マクロの$arg形式または$$arg形式のどちらを使用して参照されているかにかかわらず、文字列マクロ引数の内部で展開されます。 defaultargsオプションを設定している場合、$$argの形式で参照される未指定の引数は、値が空の文字列("")になります。
ターゲット・プロセスID
-pオプションを使用して指定するか、dtraceコマンドで-cオプションを使用して作成した、特定のユーザー・プロセスに適用されるスクリプトを作成する場合は、$targetマクロ変数を使用します。 コマンドラインで指定した、または-sオプションで指定したDプログラムは、プロセスの作成後または取込み後に、$target変数がこれらの最初のプロセスのプロセスIDを表す整数に展開された後でコンパイルされます。
たとえば、次のDスクリプトを使用して、特定の従属プロセスによって実行されるシステム・コールの分布を検索できます。 syscall.dという名前のファイルに保存します。
syscall:::entry
/pid == $target/
{
@[probefunc] = count();
}
dateコマンドによって実行されるシステム・コール数を見つけるには、このスクリプトをsyscall.dという名前のファイルに保存して、次のコマンドを実行します:
sudo dtrace -s syscall.d -c date
args[]
現在のプローブへの型付きおよびマップされた引数(存在する場合)。 args[]配列には、整数索引を使用してアクセスします。 dtrace -l -vを使用し、Argument Typesで各プローブの各引数のタイプを確認します。 たとえば、システム・コールprlimit()を考えてみます。 manページ(man -s 2 prlimit)のプロトタイプは、そのDTraceプローブ・リスト(dtrace -lvn 'syscall:vmlinux:prlimit*:entry' | grep args)と一致しています。 具体的には、引数2 (NULL以外の場合)は、リクエストされたリソース制限を持つstruct rlimitを指し、次の方法でトレースできます:
syscall:vmlinux:prlimit*:entry
/args[2] != NULL/
{
printf("request limit %d for resource %d\n", args[2]->rlim_cur, args[1]);
}
arg0, …, arg9
int64_t arg0, ..., arg9
arg0、arg1などは、プローブへの最初の10個の入力引数で、64ビット整数として表されます。 値は、現在のプローブに定義されている引数に対してのみ有効です。 たとえば、コマンドdtrace -lvn 'rawfbt:vmlinux:ksys_write:entryは、プローブに型付き引数がないことを示します。 ただし、カーネル関数ksys_write()には、書き込まれるバッファを指すarg1があることがわかります。 次のものを使用してアクセスできます: rawfbt:vmlinux:ksys_write:entry
/pid == $target/
{
printf("%s\n", stringof(arg1));
}curthread
vmlinux`struct task_struct * curthread
組込み変数curthreadは、vmlinuxデータ型を参照します。そのメンバーは、インターネットで"task_struct"を検索することで調べられます。
epid
uint_t epid
組込み変数epidは、現在のプローブの有効なプローブID (EPID)を参照します。 この整数は、特定の述語と一連の関数によって有効化された特定のプローブを一意に識別します。
fds
fileinfo_t fds[]
組込みのvariable fds[]は、現在のプロセスがfileinfo_t配列で開いたファイルを含む配列で、ファイル記述子番号で索引付けされます。 「fileinfo_t」を参照してください。
id
uint_t id
組込み変数idは、現在のプローブのプローブIDを参照します。 このIDは、DTraceによって発行されたシステム全体にわたるプローブの一意の識別子であり、dtrace -lの出力にリストされます。
ipl
uint_t ipl
組込み変数iplは、プローブの起動時に現在のCPUで割込み優先レベル(IPL)を参照します。
ノート:
この値は、割込みが発生した場合はゼロ以外で、それ以外の場合はゼロです。 ゼロ以外の値は優先使用が有効かどうか(および他の要因)によって異なり、カーネルのリリースやカーネルの構成によって変わる可能性があります。
timestamp
uint64_t timestamp
組込み変数timestampは、ナノ秒タイムスタンプ・カウンタの現在の値を参照します。 このカウンタは、過去の任意の時点から増分します。 そのため、相対計算にはtimestampカウンタのみを使用してください。