このドキュメントで説明するソフトウェアは、Extended SupportまたはSustaining Supportのいずれかにあります。 詳細は、https://www.oracle.com/us/support/library/enterprise-linux-support-policies-069172.pdfを参照してください。
Oracleでは、このドキュメントに記載されているソフトウェアをできるだけ早くアップグレードすることをお薦めします。

機械翻訳について

11.6.9 投機

DTraceの投機トレース機能では、暫定的にデータをトレースし、後でそのデータをトレース・バッファにコミットするか、または破棄するかを決定できます。 述語は、不要なイベントを除外するための主要なメカニズムです。 述語は、プローブの起動時にそのプローブ・イベントが有用であるかどうかがわかっている場合に便利です。 ただし、一部の状況では、プローブの起動後までそのプローブ・イベントが有用であるかどうかがわからないことがあります。

たとえば、システム・コールがerrnoのエラー・コードによって失敗することがある場合、エラー条件につながるコード・パスを調査するのが適切です。 1つ以上のプローブの場所にあるトレース・データを投機バッファに書き込み、後で別のプローブの場所にある主バッファにコミットするデータを選択できます。 結果として、トレース・データには有用な出力のみが含まれ、後処理は必要とされず、DTraceのオーバーヘッドは最小化されます。

投機バッファを作成するには、speculation()関数を使用します。 この関数によって投機識別子が返されるため、それをspeculate()関数に対する後続のコールで使用します。

speculate()関数は、節でデータ記録アクションを実行する前にコールします。 DTraceは、節で記録された後続のすべてのデータを投機バッファに転送します。 任意の節で作成できる投機は、1つのみです。

通常、投機識別子をスレッド固有変数に割り当て、その変数をspeculate()に対する引数としたり、他のプローブに対する述語として使用します。 次に例を示します。

#!/usr/sbin/dtrace -Fs

syscall::open:entry
{
  /*
   * The call to speculation() creates a new speculation. If this fails,
   * dtrace will generate an error message indicating the reason for
   * the failed speculation(), but subsequent speculative tracing will be
   * silently discarded.
   */
  self->spec = speculation();
  speculate(self->spec);

  /*
   * Because this printf() follows the speculate(), it is being
   * speculatively traced; it will only appear in the data buffer if the
   * speculation is subsequently commited.
   */
  printf("%s", copyinstr(arg0));
}

syscall::open:return
/self->spec/
{
  /*
   * To balance the output with the -F option, we want to be sure that
   * every entry has a matching return. Because we speculated the
   * open entry above, we want to also speculate the open return.
   * This is also a convenient time to trace the errno value.
   */
  speculate(self->spec);
  trace(errno);
}

保持する必要のあるデータが投機バッファに含まれる場合、commit()関数を使用してその内容を主バッファにコピーします。 投機バッファの内容を削除する場合、discard()関数を使用します。 次の節の例では、errno変数の値に基づいて投機バッファをコミットまたは破棄しています。

syscall::open:return
/self->spec && errno != 0/
{
  /*
   * If errno is non-zero, we want to commit the speculation.
   */
  commit(self->spec);
  self->spec = 0;
}

syscall::open:return
/self->spec && errno == 0/
{
  /*
   * If errno is not set, we discard the speculation.
   */
  discard(self->spec);
  self->spec = 0;
}

このスクリプトを実行すると、open()システム・コールが失敗したときに次の例のような出力が生成されます。

# ./specopen.d
dtrace: script ’./specopen.d’ matched 4 probes
CPU FUNCTION
  1  => open                                  /var/ld/ld.config
  1  <= open                                          2
  1  => open                                  /images/UnorderedList16.gif
  1  <= open                                          4
...