前回はDTraceを用いて関数呼び出しフローを採取しました。今回は,
引数値の採取
関数呼び出しにおいて採取したい情報の筆頭は,
引数値の表示
まずは,multiply()
を持つプログラムshow_
リスト1 採取対象関数multiply()
)
int
multiply(int x, int y)
{
return (x * y);
}
この関数が呼び出された際の引数を表示するDスクリプトは,show_
およびmultiply
部分を適宜書き換えてください)。
リスト2 引数値採取Dスクリプト
pid$target:show_args:multiply:entry
{
printf("multiply(%d, %d)\n", arg0, arg1);
}
上記Dスクリプトの各要素は,pid$target:show_
" および"entry
"部分に関しては,
表1 Dスクリプトの構成要素
multiply |
この位置には情報採取対象の関数名を記述します。 この例では, multiply 関数が採取対象となります。
|
---|---|
printf() |
C 標準ライブラリの printf()
関数に相当する処理を行う DTraceアクションを呼び出します。標準Cライブラリで既定されているフォーマット指定は概ね使用可能です。 |
arg0 , arg1 |
(この例では) 最初の引数が arg0 ,arg1 ,arg2 ...で参照可能です。範囲外の引数を参照した場合の値は不定となります。 |
dtrace
コマンドの起動方法は前回と同様です。
図1 引数値の採取
$ dtrace -s watch_arg_val.d \
-q \
-c './show_args 13 17'
multiply(13, 17) ← 採取結果
$
今回は関数フローの必要が無いので,-F
指定を省略しています。
また -q
指定により,printf()
アクションによる)
D スクリプトの文法詳細
これまでは,
D スクリプトは,
リスト3 Dスクリプト文法
<Probe-Description> [, ....]
{
[<Action> ....]
}
<Action>
部分は,printf()
のような処理を,
<Probe-Description>
は以下の形式で構成されます。
リスト4 <Probe-Description>
の構成
<Provider>:<ProbeModule>:<ProbeFunc>:<ProbeName>
各要素は以下の意味を持ちます。
表2 <Probe-Description>
の構成要素
<Provider> |
情報採取機能の種類を指定します。この機能種別を DTrace ではプロバイダ ユーザプログラムからの情報採取の場合は, pid プロバイダの使用がメインになると思いますが, |
---|---|
<ProbeModule> |
情報採取対象のバイナリファイル名を指定します。 現状は採取対象コマンド名と同一とみなして構いません |
<ProbeFunc> |
情報採取対象となる関数名を指定します。 |
<ProbeName> |
どの時点で情報を採取するかを指定します。pid プロバイダを使用する場合,entry return |
上記の各要素の組み合わせによって特定される
<ProbeModule>
と<ProbeFunc>
が採取対象となる関数<Provider>
と<ProbeName>
が採取対象となる情報
<Probe-Description>
中の各要素は省略可能で,
ただし,pid
プロバイダを使用してユーザプログラムから情報採取する場合,<ProbeFunc>
ぐらいだと思ってください
<Action>
が実行される際の採取対象プローブに関する<Probe-Description>
中の各要素は,probeprov
,probemod
,probefunc
および probename
という組み込み変数を使って参照することができます。
そのため,<Probe-Description>
はカンマで区切って複数列挙できることと,<Action>
の対象となっている関数名をprobefunc
参照できることを利用して:
リスト5 <Action>
共有例
pid$target:show_args:add:entry,
pid$target:show_args:subtract:entry,
pid$target:show_args:multiply:entry,
pid$target:show_args:divide:entry
{
printf("%s(%d, %d)\n", probefunc, arg0, arg1);
}
上記のように,<Action>
を,<Probe-Description>
で共有しつつ,
上記以外の組み込み変数に関しては,
- ※1)
- 厳密には,
これでもまだ完全な定義ではありませんが, 今回省略した要素に関しては, 連載中の各回で必要に応じて補足します。 - ※2)
pid
プロバイダで<ProbeName>
を省略した場合,理屈上は暗黙で entry
およびreturn
が指定されたもの,とみなされるはずなのですが, このような省略指定をすると何故か -F
による関数フローが綺麗に表示されません(各関数が重複して表示されてしまいます)。