ライブラリや実行可能ファイルの DTrace プローブは、対応するアプリケーションバイナリの ELF セクションに定義されます。この節では、プローブを定義し、アプリケーションのソースコードに追加することにより、アプリケーションの構築プロセスに DTrace プローブ定義を追加する方法について説明します。
.d ソースファイルに DTrace プローブを定義します。このソースファイルは、あとでアプリケーションのコンパイルとリンク時に使用されます。まず、適切なユーザーアプリケーションプロバイダの名前を選択します。アプリケーションコードを実行している各プロセスのプロセス ID に、選択したプロバイダ名が追加されます。たとえば、プロセス ID 1203 で実行されている Web サーバー用としてプロバイダ名 myserv を選択した場合、このプロセスに対応する DTrace プロバイダ名は myserv1203 になります。.d ソースファイルに、次のようなプロバイダ定義を追加します。
provider myserv { ... };
次に、各プローブとその引数の定義を追加します。次の例では、「プローブポイントの選択」で説明した 2 つのプローブを定義しています。最初のプローブは、string 型の引数を 2 つとります。2 番目のプローブは引数をとりません。D コンパイラは、プローブ名に含まれる 2 つの連続した下線 (--) を単一のハイフン (-) に変換します。
provider myserv { probe query__receive(string, string); probe query__respond(); };
プロバイダ定義には安定性属性を追加して、プローブの使用者がアプリケーションの将来のバージョンでの変更可能性について判断できるようにしてください。DTrace の安定性属性の詳細については、第 39 章安定性を参照してください。以下は、安定性属性の定義例です。
#pragma D attributes Evolving/Evolving/Common provider myserv provider #pragma D attributes Private/Private/Unknown provider myserv module #pragma D attributes Private/Private/Unknown provider myserv function #pragma D attributes Evolving/Evolving/Common provider myserv name #pragma D attributes Evolving/Evolving/Common provider myserv args provider myserv { probe query__receive(string, string); probe query__respond(); };
ユーザーが追加したプローブの整数でない引数を D スクリプト内で使用する場合、copyin() および copyinstr() 関数を使ってそれらの引数を取得する必要があります。詳細については、第 33 章ユーザープロセスのトレースを参照してください。
.d ファイルを使ってプローブを定義できたら、ソースコードに、プローブがトリガーされる位置の情報を追加する必要があります。次のような C アプリケーションソースコードがあるとします。
void main_look(void) { ... query = wait_for_new_query(); process_query(query) ... }
プローブの位置の情報を追加するには、<sys/sdt.h>に定義されている DTRACE_PROBE() マクロの参照を追加します。次の例を参照してください。
#include <sys/sdt.h> ... void main_look(void) { ... query = wait_for_new_query(); DTRACE_PROBE2(myserv, query__receive, query->clientname, query->msg); process_query(query) ... }
マクロ名 DTRACE_PROBE2 の接尾辞 2 は、プローブに渡される引数の数を表します。プローブマクロの最初の 2 つの引数は、プロバイダ名とプローブ名です。これらはそれぞれ、D プロバイダ定義とプローブ定義に一致していなければなりません。残りのマクロ引数は、プローブの起動時に DTrace arg0..9 変数に割り当てられる引数です。アプリケーションソースコード内で同じプロバイダ名やプローブ名を繰り返し参照できます。ソースコード内で同じプローブが何回も参照されている場合、そのいずれかがプローブを起動することになります。
アプリケーションの構築プロセスに、DTrace プロバイダとプローブの定義を追加する必要があります。通常の構築プロセスでは、各ソースファイルがコンパイルされ、対応するオブジェクトファイルが生成されます。次に、このコンパイルされたオブジェクトファイルが互いにリンクされることにより、最終的なアプリケーションバイナリが完成します。次の例を参照してください。
cc -c src1.c cc -c src2.c ... cc -o myserv src1.o src2.o ... |
アプリケーションに DTrace プローブ定義を追加するには、構築プロセスに適切な Makefile 規則を追加して、dtrace コマンドを実行します。次の例を参照してください。
cc -c src1.c cc -c src2.c ... dtrace -G -32 -s myserv.d src1.o src2.o ... cc -o myserv myserv.o src1.o src2.o ... |
この dtrace コマンドは、コンパイラコマンドによって生成されたオブジェクトファイルに後処理を施すことにより、myserv.d とその他のオブジェクトファイルから myserv.o という名前のオブジェクトファイルを生成します。プロバイダ定義とプローブ定義をユーザーアプリケーションにリンクするには、dtrace -G オプションを使用します。32 ビットアプリケーションバイナリを構築するには、-32 オプションを使用します。64 ビットアプリケーションバイナリを構築するには、-64 オプションを使用します。