pid プロバイダでは、ユーザープロセス内の関数の開始 (entry) と終了 (return) のトレースと、絶対アドレスまたは関数オフセットで指定した命令のトレースを行うことができます。プローブが有効にされていなければ、pid プロバイダの及ぼすプローブの影響は皆無です。プローブが有効にされていれば、トレース対象のプロセスだけがプローブの影響を受けます。
コンパイラによって関数がインライン展開されても、pid プロバイダのプローブは起動されません。コンパイル時に関数がインライン展開されないようにするには、コンパイラのマニュアルを参照してください。
関数ポインタを使ってサブ関数を呼び出す関数を pid プロバイダがプローブすると、予期しない動作になります。関数に入るときのアドレスと関数から戻るときのアドレスに明示的にプローブを置くことで、そのような関数を解析することができます。
pid プロバイダは、実際は、複数のプロバイダから成る「クラス」を定義します。プロセスごとに固有の pid プロバイダを関連付けることができます。たとえばプロセス ID 123 のプロセスをトレースしたい場合は、pid123 プロバイダを使用します。このようなプロバイダから提供されるプローブでは、プローブ記述のモジュール部分が、対応するプロセスのアドレス空間にロードされたオブジェクトを示します。以下は、mdb(1) を使ってオブジェクトのリストを表示する例です。
$ mdb -p 1234 Loading modules: [ ld.so.1 libc.so.1 ] > ::objects BASE LIMIT SIZE NAME 10000 34000 24000 /usr/bin/csh ff3c0000 ff3e8000 28000 /lib/ld.so.1 ff350000 ff37a000 2a000 /lib/libcurses.so.1 ff200000 ff2be000 be000 /lib/libc.so.1 ff3a0000 ff3a2000 2000 /lib/libdl.so.1 ff320000 ff324000 4000 /platform/sun4u/lib/libc_psr.so.1 |
プローブ記述内では、ファイル名 (完全パス名ではない) でオブジェクトに名前を付けます。接尾辞 .1、so.1 は省略することもできます。以下の例では、すべて同じプローブに名前を付けています。
pid123:libc.so.1:strcpy:entry pid123:libc.so:strcpy:entry pid123:libc:strcpy:entry
最初の例はプローブの実際の名前です。残りの 2 つの例は別名です。これらの別名は、内部で完全ロードオブジェクト名に置き換えられます。
実行可能ファイルのロードオブジェクトには、別名 a.out を使用できます。次の 2 つのプローブ記述は、同じプローブに名前を付けています。
pid123:csh:main:return pid123:a.out:main:return
アンカーされた DTrace プローブの場合と同様に、プローブ記述の関数フィールドを使って、モジュールフィールド内の関数に名前を付けます。ユーザーアプリケーションバイナリでは、同じ関数に複数の名前が付けられていることがあります。たとえば、mutex_lock は libc.so.1 内の関数 pthread_mutex_lock の代替名になります。DTrace は、このような関数に対して正規名を 1 つ選択し、これを内部で使用します。以下の例では、DTrace がモジュール名と関数名を正規の形式に再マッピングする内部手続きの様子を確認できます。
# dtrace -q -n pid101267:libc:mutex_lock:entry'{ \ printf("%s:%s:%s:%s\n", probeprov, probemod, probefunc, probename); }' pid101267:libc.so.1:pthread_mutex_lock:entry ^C |
この自動リネームにより、有効にする前と実際に有効にしたあとで、プローブ名が若干変化することがあります。同じ Solaris リリースを実行しているシステム同士であれば、DTrace をいつ実行しても、正規名は常に同じです。
pid プロバイダの効果的な使用例については、第 33 章ユーザープロセスのトレースを参照してください。
FBT プロバイダを使用するとカーネル内の関数の開始 (entry) と終了 (return) をトレースすることができるのと同様に、pid プロバイダには、ユーザープログラム内の関数の開始 (entry) と終了 (return) をトレースする機能があります。このマニュアルでは、FBT プロバイダを使ってカーネル関数呼び出しをトレースする例をいくつか紹介していますが、これらの例をほんの少し変更するだけでユーザープロセスにも適用することができます。
entry プローブは、トレース対象の関数が呼び出されたときに起動します。entry プローブの引数は、トレース対象の関数の引数の値と一致します。
return プローブは、トレース対象の関数が復帰したとき、または別の関数の末尾呼び出しを行なったときに起動します。arg0 には復帰命令の関数のオフセット、arg1 には戻り値が入ります。
argN を使用すると、フィルタリングされていない生の値が型 int64_t として返されます。pid プロバイダでは args[N ] 書式はサポートされません。
pid プロバイダを使用すると、関数内のあらゆる命令をトレースできます。たとえば、関数 main() 内に 4 バイトの命令をトレースするには、次のようなコマンドを使用します。
pid123:a.out:main:4
このプローブは、main+4 のアドレスでこの命令が実行されるたびに起動します。オフセットプローブの引数は未定義です。これらのプローブが設定されている位置でプロセスの状態を確認したい場合は、uregs[] 配列が便利です。詳細については、「uregs[] 配列」を参照してください。
以下の表に、pid プロバイダの安定性を DTrace の安定性機構に従って示します。安定性機構の詳細については、第 39 章安定性を参照してください。
要素 |
名前の安定性 |
データの安定性 |
依存クラス |
---|---|---|---|
プロバイダ |
発展中 |
発展中 |
ISA |
モジュール |
非公開 |
非公開 |
不明 |
機能 |
非公開 |
非公開 |
不明 |
名前 |
発展中 |
発展中 |
ISA |
引数 |
非公開 |
非公開 |
不明 (Unknown) |