これまでの連載における説明では、pidプロバイダが提供するプローブentryおよびreturn)
しかし、
そこで、
今回は、
ソースファイルの準備
以下の手順で必要となるソースファイルを準備します。
プロバイダの定義
何をおいても、
リスト1 独自プロバイダの定義
(checkpoint.)
provider checkpoint {
pass(const char* filename, int lineno);
};
プロバイダcheckpointが提供するプローブpassは、
プログラムの要所要所に埋め込まれたプローブ位置において、ファイル名と行番号情報を採取することで、実行時にどのような経路を通過したのかを知る
つまり、
なおプロバイダ定義を記述する際には、{ }" の後ろ)
ヘッダファイルの生成
独自プロバイダを定義したならば、dtraceコマンドを実行してください。
図1 ヘッダファイルの生成
(checkpoint.)
$ dtrace -s checkpoint.d -h
独自プロバイダを定義したDスクリプトの指定-s" オプション)-h" オプションを指定することで、checkpoint.が生成されます。
:
#define CHECKPOINT_PASS(arg0, arg1) \
__dtrace_checkpoint___pass(arg0, arg1)
:
:
extern void __dtrace_checkpoint___pass(char *, int);
:
"-h"オプション指定によってdtraceコマンドが生成するヘッダファイルでは、
通常は、
リスト2の例に見られるように、__)
ユーティリティヘッダの定義
先述したように、dtraceコマンドによって生成されたヘッダファイルと、passのようなプローブの場合、checkpoint_を定義しましょう。
リスト3 ユーティリティヘッダの作成
(checkpoint_)
#include "checkpoint.h"
#define DTRACE_CHECKPOINT_PASS() \
CHECKPOINT_PASS(__FILE__, __LINE__)
CHECKPOINT_マクロを直接使用するのではなく、DTRACE_マクロを使うことで、
Cプログラムの実装
今回独自に定義したpassプローブの埋め込み対象として、main()に持つプログラムを想定します。
リスト4 プローブ埋め込み対象プログラム
(branch_)
if(argc < 2){
DTRACE_CHECKPOINT_PASS();
}
else{
int val = atol(argv[1]);
DTRACE_CHECKPOINT_PASS();
if(val < 10){
DTRACE_CHECKPOINT_PASS();
}
else{
DTRACE_CHECKPOINT_PASS();
}
}
DTRACE_CHECKPOINT_PASS();
この実装では与えられた引数に応じて条件分岐を行いますが、pidプロバイダによる関数フロー採取では、
そこで、passプローブを使用することで、
実行可能ファイルの生成
Cプログラムのコンパイル
プローブ埋め込み対象のCプログラム
$ cc -c branch_by_arg.c
ここでのコンパイルにはDTraceの独自プローブ埋め込みの影響はありませんから、
Cプログラムのリンク
コンパイルによって生成された、
$ cc -o branch_by_arg branch_by_arg.o
Undefined first referenced
symbol in file
__dtrace_checkpoint___pass branch_by_arg.o
ld: fatal: symbol referencing errors. \
No output written to branch_by_arg
$
上記実行例で、checkpoint.におけるCHECKPOINT_マクロ)
dtraceコマンドにより生成されたのはヘッダファイルのみですし、
実はユーザプログラムに独自プローブを埋め込む場合、dtraceコマンドによる前処理を行う必要があります。
dtraceコマンドによるリンク前処理は、-G"オプションと、
dtraceコマンドによるリンク前処理$ dtrace -s checkpoint.d -G branch_by_arg.o
"
前処理が完了したなら、 リンク時オプションに関しても、 なお、 一部のソースファイルを改変してから再度リンクを行う場合、 独自に定義したプロバイダからの情報採取の要領は、 リスト5に、 それでは、 引数によって分岐した先で Emacsやviのエラー行ジャンプ機能と併用すれば、 今回は独自プロバイダの定義を行いましたが、 定義/ 次回は、-G"オプションが指定された場合、dtraceコマンドは以下の処理を実施します。
__"関数)checkpoint.)dtraceコマンドにより生成されたオブジェクトファイルを含めて、$ cc -o branch_by_arg branch_by_arg.o checkpoint.o
dtrace コマンド+"-G"オプションによる前処理は、makeコマンド等で自動化する場合には、プローブからの情報採取
pidプロバイダの場合と同じcheckpointプロバイダのpassプローブを使用するDスクリプトの例を示します。passプローブを使用するDスクリプトcheckpoint$target:$1::pass
{
printf("%s:%d:%s\n",
copyinstr(arg0), arg1, probefunc);
}
passプローブからの情報採取$ dtrace -s watch_checkpoint.d \
-q \
-c './branch_by_arg 13'
branch_by_arg.c:15:main
branch_by_arg.c:21:main
branch_by_arg.c:25:main
$
DTRACE_マクロを通過するつど、次回予告