SDT(9) | FreeBSD Kernel Developer's Manual | SDT(9) |
名称
SDT — 静的に定義されたトレースのプローブを追加するための DTrace フレームワーク書式
#include < sys/sdt.h>SDT_PROVIDER_DECLARE( prov);
SDT_PROVIDER_DEFINE( prov);
SDT_PROBE_DECLARE( prov, mod, func, name);
SDT_PROBE_DEFINE( prov, mod, func, name, sname);
SDT_PROBE_DEFINE0( prov, mod, func, name, sname);
SDT_PROBE_DEFINE1( prov, mod, func, name, sname, arg0);
SDT_PROBE_DEFINE2( prov, mod, func, name, sname, arg0, arg1);
SDT_PROBE_DEFINE3( prov, mod, func, name, sname, arg0, arg1, arg2);
SDT_PROBE_DEFINE4( prov, mod, func, name, sname, arg0, arg1, arg2, arg3);
SDT_PROBE_DEFINE5( prov, mod, func, name, sname, arg0, arg1, arg2, arg3, arg4);
SDT_PROBE_DEFINE6( prov, mod, func, name, sname, arg0, arg1, arg2, arg3, arg4, arg5);
SDT_PROBE_DEFINE7( prov, mod, func, name, sname, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
SDT_PROBE_DEFINE0_XLATE( prov, mod, func, name, sname);
SDT_PROBE_DEFINE1_XLATE( prov, mod, func, name, sname, arg0, xarg0);
SDT_PROBE_DEFINE2_XLATE( prov, mod, func, name, sname, arg0, xarg0, arg1, xarg1);
SDT_PROBE_DEFINE3_XLATE( prov, mod, func, name, sname, arg0, xarg0, arg1, xarg1, arg2, xarg2);
SDT_PROBE_DEFINE4_XLATE( prov, mod, func, name, sname, arg0, xarg0, arg1, xarg1, arg2, xarg2, arg3, xarg3);
SDT_PROBE_DEFINE5_XLATE( prov, mod, func, name, sname, arg0, xarg0, arg1, xarg1, arg2, xarg2, arg3, xarg3, arg4, xarg4);
SDT_PROBE_DEFINE6_XLATE( prov, mod, func, name, sname, arg0, xarg0, arg1, xarg1, arg2, xarg2, arg3, xarg3, arg4, xarg4, arg5, xarg5);
SDT_PROBE_DEFINE7_XLATE( prov, mod, func, name, sname, arg0, xarg0, arg1, xarg1, arg2, xarg2, arg3, xarg3, arg4, xarg4, arg5, xarg5, arg6, xarg6);
SDT_PROBE0( prov, mod, func, name);
SDT_PROBE1( prov, mod, func, name, arg0);
SDT_PROBE2( prov, mod, func, name, arg0, arg1);
SDT_PROBE3( prov, mod, func, name, arg0, arg1, arg2);
SDT_PROBE4( prov, mod, func, name, arg0, arg1, arg2, arg3);
SDT_PROBE5( prov, mod, func, name, arg0, arg1, arg2, arg3, arg4);
SDT_PROBE6( prov, mod, func, name, arg0, arg1, arg2, arg3, arg4, arg5);
SDT_PROBE7( prov, mod, func, name, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
解説
SDT マクロによって、プログラマは、カーネルコードの静的なトレースポイントを定義することができます。これらのトレースポイントは、コードを dtrace(1) を使用して機器を備えることができる、DTrace プローブを作成するために、 SDT フレームワークによって使用されます。デフォルトで、 SDT トレースポイントは、無効にされ、周囲のコードに効果がありません。与えられたトレースポイントに対応する DTrace プローブが有効にされるとき、トレースポイントを実行するスレッドは、ハンドラを呼び出し、プローブを起動します。さらに、トレースポイントは、引数を取ることができ、有効にされたプローブを起動するとき、データを DTrace フレームワークへ渡すことを可能にします。複数のトレースポイントは、プログラマが特定のコードの実行パスにプローブを結び付けることではなく、論理システムイベントに類似する DTrace プローブを作成することを可能にし、単一の DTrace プローブに類似しています。例えば、ネットワークスタックへの IP パケットの到着に対応する DTrace プローブは、2 つの SDT トレースポイントを使用して定義されます: IPv4 パケットのための一つと IPv6 パケットのための一つです。
DTrace プローブを定義することに加えて、 SDT マクロによって、プログラマは、名前空間の論理的に関連するプローブすることを可能にして、新しい DTrace プロバイダを定義することができます。例は、FreeBSD の sctp(4) の実装のために SDT プローブを含んでいる、FreeBSD の sctp プロバイダです。
SDT_PROVIDER_DECLARE() と SDT_PROVIDER_DEFINE() マクロは、 SDT フレームワークがある prov と名前が付けられた DTrace プロバイダを宣言し、定義するためにそれぞれ使用されます。プロバイダは、一度だけ定義される必要があります。しかしながら、プロバイダは、そのプロバイダに属する、あらゆる SDT プローブを定義する前に宣言されなければなりません。
同様に、 SDT_PROBE_DECLARE() と SDT_PROBE_DEFINE*() マクロは、 SDT フレームワークを使用して DTrace プローブを宣言して、定義するために使用されます。一旦、プローブが定義されたならば、そのプローブのためのトレースポイントは、カーネルコードに追加されます。 DTrace プローブ識別子は、プロバイダ、モジュール、関数と名前から成り、それらすべては、 SDT プローブ定義で指定されます。プローブは、モジュール名を指定するべきでないことに注意してください: プローブのモジュール名は、カーネルモジュールがアンロードされるとき、それが破壊されるべきかどうか判断するために使用されます。 「バグ」 セクションを参照してください。プローブは、複数のカーネルモジュールに渡って定義されてはならないことに特に注意してください。また、 SDT_PROBE_DEFINE*() マクロは、特別の sname パラメータを取ります。これは、‘ -
’文字を含んでいる名前があるプローブの生成を許可するために使用されます。特に、 name 引数は、下線に変換されるすべてのダッシュがあるプローブ名を含んでいるべきで、 sname 引数は、D スクリプトによって参照されるプローブ名であるべきです。
また、 SDT_PROBE_DEFINE*() マクロによって、プログラマは、プローブに渡される引数のタイプを宣言することができます。これは、オプションです。 ( SDT_PROBE_DEFINE() マクロの使用を通して) 引数タイプが省略されるなら、引数を利用したいユーザは、手動で D スクリプトの正確なタイプに、それらを cast しなければなりません。プローブ定義がそれらの引数タイプの宣言を含むことは強く推奨されます。
SDT_PROBE_DEFINE*_XLATE() マクロは、引数タイプが対応する xarg 引数によって指定されたタイプにダイナミックに変換されるプローブのために使用されます。これは、他のオペレーティングシステムからプローブ定義を移植するとき、主として役に立ちます。 dtrace(1) によって見られるように、これらのマクロを使用して定義されたプローブの引数は、プローブ定義の xarg タイプと一致するタイプがあります。しかしながら、トレースポイントで渡された引数は、プローブ定義の本来の引数タイプと一致するタイプがあり、したがって、本来のタイプは、変換されたタイプに動的に変換されます。適切な変換プログラムが /usr/lib/dtrace で定義されている限り、プローブを使用するスクリプトは、与えられた SDT プローブ引数の基本的なタイプにそれら自体が関係している必要はありません。
SDT_PROBE*() マクロは、 SDT トレースポイントを作成するために使用されます。それらは、実行形式のコードに追加される必要があり、それらが呼び出されるコードを設置するために使用することができます。
使用例
次のプローブ定義は、カーネルがタイプ Destination Unreachable の ICMP パケットを受信するとき、仮定としてトリガされる、呼び出された‘icmp::unreach:pkt-receive
’を DTrace プローブを作成します。
SDT_PROVIDER_DECLARE(icmp); SDT_PROBE_DEFINE1(icmp, , unreach, pkt_receive, pkt-receive, "struct icmp *");
特に、このプローブは、単一の引数を取ります: パケットのための ICMP ヘッダを含んでいる構造体へのポインタ。このプローブのモジュール名は、指定されないことに注意してください。
ネットワークスタックが IP パケットを受信するとき、起動する DTrace プローブを考慮してください。そのようなプローブは、複数のトレースポイントによって定義されます:
SDT_PROBE_DEFINE3(ip, , , receive, receive, "struct ifnet *", "struct ip *", "struct ip6_hdr *"); int ip_input(struct mbuf *m) { struct ip *ip; ... ip = mtod(m, struct ip *); SDT_PROBE3(ip, , , receive, m->m_pkthdr.rcvif, ip, NULL); ... } int ip6_input(struct mbuf *m) { struct ip6_hdr *ip6; ... ip6 = mtod(m, struct ip6_hdr *); SDT_PROBE3(ip, , , receive, m->m_pkthdr.rcvif, NULL, ip6); ... }
特に、プローブは、カーネルが IPv4 パケットまたは IPv6 パケットのいずれかを受信するとき、起動するべきです。
上記の ICMP プローブの議論を考慮してください。その 2 番目の引数が、RFC 792 で定義されている、ICMP パケットの ICMP ヘッダを表わすために FreeBSD カーネルで定義されたタイプである、タイプ struct icmp であることを注意します。 Linux は、同じ目的のために、対応するタイプ struct icmphdr がありますが、そのフィールド名は、FreeBSD の struct icmp と異なります。同様に、illumos は、再び異なるフィールド名で icmph_t タイプを定義しています。すべての 3 つのオペレーティングシステムで定義される‘ icmp:::pkt-receive
’プローブでさえ、まだ、ICMP ヘッダ引数の与えられたフィールドを抽出するための OS 特有のスクリプトを書かなければなりません。動的に変換されたタイプは、次の問題を解決します: ICMP ヘッダを表わす OS 独立の c(7) 構造体を定義することができ、例えば、 struct icmp_hdr_dt と 3 つの OS 特有のタイプの各々から dtrace(1) ライブラリのパスのすべての struct icmp_hdr_dt まで、変換プログラムを定義します、次に、上記の FreeBSD のプローブを、次で定義することができます:
SDT_PROBE_DEFINE1_XLATE(ip, , , receive, receive, "struct icmp *", "struct icmp_hdr_dt *");
関連項目
dtrace(1)作者
DTrace と SDT SDT フレームワークは、 <jb@FreeBSD.org>によって Solaris から FreeBSD に最初に移植されました。このマニュアルページは、 <markj@FreeBSD.org>によって書かれました。バグ
SDT マクロによって、プローブ定義の一部としてプローブのモジュール名を指定することができます。しかしながら、DTrace フレームワークは、カーネルモジュールがアンロードされるとき、どのプローブを破壊しなければならないか決定するためにプローブのモジュール名を使用するので、プローブのモジュール名は、定義されたモジュールの名前と一致するべきです。 SDT は、プローブ定義で指定されないままであるなら、モジュール名を適切に設定します。 「使用例」 を参照してください。(FreeBSD のポートの拡張によって) オリジナルの SDT 実装のゴールの 1 つは、不活性の SDT プローブは、性能に影響をあたえるべきでないということです。これは、不運にも事実と異なります。 SDT トレースポイントは、それらが定義されているコードに少量の 0 でない待ち時間の量を追加します。プローブのより洗練された実装は、この問題を軽減するための助けとなります。
August 17, 2013 | FreeBSD |