6 DTraceの組込み変数リファレンス

DTraceには、Dプログラムやスクリプトで使用できる組込みスカラー変数のセットが含まれます。

マクロ変数

マクロ変数は、実行時に移入される変数であり、実行中のdtraceプロセスやコンパイラを実行しているプロセスに関する情報を識別します。

Dコンパイラには、Dプログラムやインタプリタ・ファイルを記述するときに使用できる組込みマクロ変数のセットが定義されています。マクロ変数は接頭辞としてドル記号($)が付く識別子であり、入力ファイルまたはスクリプトの処理時に、Dコンパイラによって1回展開されます。次の表では、Dコンパイラに用意されているマクロ変数について説明します。

表6-1 Dのマクロ変数

名前 説明 参照先

$[0-9]+

マクロ引数

マクロ引数」を参照

$egid

実効グループID

getegid(2)のマニュアル・ページを参照してください

$euid

実効ユーザーID

geteuid(2)のマニュアル・ページを参照してください

$gid

実グループID

getgid(2)のマニュアル・ページを参照してください

$pid

プロセスID

getpid(2)のマニュアル・ページを参照してください

$pgid

プロセス・グループID

getpgid(2)のマニュアル・ページを参照してください

$ppid

親プロセスID

getppid(2)のマニュアル・ページを参照してください

$sid

セッションID

getsid(2)のマニュアル・ページを参照してください

$target

ターゲット・プロセスID

ターゲット・プロセスID」を参照

$uid

実ユーザーID

getuid(2)のマニュアル・ページを参照してください

展開後の変数は、現在の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コンパイラはこの引数の値を二重引用符で囲まれた文字列とみなすようになります。通常のD文字列エスケープ・シーケンス(表3-6を参照)はすべて、文字列形式のマクロ引数の内部で展開されます。これは、$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[]配列へのアクセスには整数索引が使用されますが、各要素は、特定のプローブ引数に対応する型として定義されます。型付き引数の情報については、詳細オプション-vとともにdtrace -lを使用して、Argument Typesを確認します。

arg0, …, arg9

int64_t arg0, ..., arg9

組込み変数arg0arg1などは、プローブへの最初の10個の入力引数を表し、64ビットのRAW整数として表現されます。値は、現在のプローブに定義されている引数に対してのみ有効です。

caller

uintptr_t caller

組込み変数callerは、プローブが起動した時点における現在のカーネル・スレッドのプログラム・カウンタの位置を参照します。

curcpu

cpuinfo_t * curcpu

組込み変数curcpuは、現在の物理CPUを参照します。

curthread

vmlinux`struct task_struct * curthread

組込み変数curthreadは、vmlinuxデータ型を参照します。そのメンバーは、インターネットで"task_struct"を検索することで調べられます。

epid

uint_t epid

組込み変数epidは、現在のプローブの有効なプローブID (EPID)を参照します。この整数は、特定の述語と一連の関数によって有効化された特定のプローブを一意に識別します。

errno

int errno

組込み変数errnoは、このスレッドによって最後に実行されたシステム・コールが返したエラー値を参照します。

execname

string execname

組込み変数execnameは、現在のプロセスを実行するためにexecve()に渡された名前を参照します。

gid

gid_t gid

組込み変数gidは、現在のプロセスの実グループIDを参照します。

id

uint_t id

組込み変数idは、現在のプローブのプローブIDを参照します。このIDは、DTraceによって発行されたシステム全体にわたるプローブの一意の識別子であり、dtrace -lの出力にリストされます。

ipl

uint_t ipl

組込み変数iplは、プローブの起動時に現在のCPUで割込み優先レベル(IPL)を参照します。

ノート:

この値は、割込みが発生した場合はゼロ以外で、それ以外の場合はゼロです。ゼロ以外の値は優先使用が有効かどうか(および他の要因)によって異なり、カーネルのリリースやカーネルの構成によって変わる可能性があります。

pid

pid_t pid

組込み変数pidは、現在のプロセスのプロセスIDを参照します。

ppid

pid_t ppid

組込み変数ppidは、現在のプロセスの親プロセスIDを参照します。

probefunc

string probefunc

組込み変数probefuncは、現在のプローブの記述の関数名部分を参照します。

probemod

string probemod

組込み変数probemodは、現在のプローブの記述のモジュール名部分を参照します。

probename

string probename

組込み変数probenameは、現在のプローブの記述の名前部分を参照します。

probeprov

string probeprov

組込み変数probeprovは、現在のプローブの記述のプロバイダ名部分を参照します。

stackdepth

uint32_t stackdepth

組込み変数stackdepthは、プローブ起動時の現在のスレッドのスタック・フレームの深さを参照します。

tid

id_t tid

組込み変数tidは、現在のプロセスのタスクIDを参照します。

timestamp

uint64_t timestamp

組込み変数timestampは、ナノ秒タイムスタンプ・カウンタの現在の値を参照します。このカウンタは、過去の任意の時点から増分します。そのため、相対計算にはtimestampカウンタのみを使用してください。

ucaller

uint64_t ucaller

組込み変数ucallerは、プローブが起動した時点における現在のユーザー・スレッドのプログラム・カウンタの場所を参照します。

uid

uid_t uid

組込み変数uidは、現在のプロセスの実ユーザーIDを参照します。

uregs

uint64_t uregs[]

プローブ起動時の現在のスレッドの保存されたユーザー・モード・レジスタ値。

ustackdepth

uint32_t ustackdepth

組込み変数ustackdepthは、プローブ起動時のユーザー・スレッドのスタック・フレームの深さを参照します。

vtimestamp

uint64_t vtimestamp

組込み変数vtimestampは、ナノ秒タイムスタンプ・カウンタの現在の値を参照します。CPU上で現在のスレッドが実行されている合計時間から、DTraceの述語と関数で使用された時間を引いた値として仮想化されます。このカウンタは、過去の任意の時点から増分します。そのため、相対計算にはvtimestampカウンタのみを使用してください。

walltimestamp

int64_t walltimestamp

組込み変数walltimestampは、1970年1月1日の協定世界時00:00から現在のナノ秒数を参照します。