DTraceのコンポーネントと用語
プローブ
DTraceは、プローブを使用することで動作します。これには、カーネルまたはユーザー空間アプリケーション内の特定のインストゥルメンテーションを識別するものや、間隔カウンタやパフォーマンス・イベント・カウンタを識別するために使用できるものがあります。 プローブは、特定のコードの実行時や特定のカウンタの増分時などのイベントによって起動し、DTraceはプログラムやスクリプトでイベントにバインドされた関数を実行できます。 たとえば、プローブは特定のファイルが開かれたときに起動でき、DTraceプログラムは問題のデバッグや解決に役立つイベントに関連する情報を出力できます。 同様に、DTraceがトレース・アクティビティを開始または終了した時点で、これらのアクション専用のBEGINおよびENDプローブは常に起動します。
システムで使用可能なすべてのプローブは、次のコマンドを入力することでリストできます。
sudo dtrace -l出力には、プローブを正しく参照するために使用する各値が表示されます。
ID PROVIDER MODULE FUNCTION NAME
1 dtrace BEGIN
2 dtrace END
3 dtrace ERROR
4 syscall vmlinux read entry
5 syscall vmlinux read return
6 syscall vmlinux write entry
7 syscall vmlinux write return
...特定のプローブをリストして有効にする方法の詳細は、「プローブのリストと有効化」を参照してください。
プローブは、特定の種類のインストゥルメンテーションをグループにまとめるプロバイダによって使用できるようになります。 プロバイダがソースコードに関連している場合、そのプローブには、モジュールと関数の識別子でプローブが関連しているコード部分についての情報も含まれることがあります。 そのため、プローブはプルーブ記述で識別され、次の4つのフィールドにグループ化されます:
- provider
-
プローブが属するDTraceプロバイダの名前。
- module
-
プローブが特定のプログラムの場所に対応している場合は、そのプローブがあるカーネル・モジュール、ライブラリまたはユーザー空間プログラムの名前。 一部のプローブは、より抽象的なトレース・ポイントに関連する場合、特定のソースの場所に拘束されないモジュール名に関連付けられていることがあります。
- function
-
プローブが特定のプログラムの場所に対応している場合は、そのプローブがあるプログラム関数の名前。
- name
-
プローブのセマンティックな意味がわかる名前(
BEGINやENDなど)。
プローブを参照するときには、プローブ記述の4つの部分のすべてをコロンで区切って記述します:
provider:module:function:name一部のプローブには、リスト表示時にモジュールまたは関数識別子がありません。 こうしたプローブの完全なプローブ記述を指定するときには、空のフィールドも含める必要があります:
dtrace:::BEGIN プローブにはモジュールと関数は必要ありません。 dtraceのBEGIN、ENDおよびERRORプローブは、特定のインストゥルメントされるプログラムの関数または場所に対応していないため、この好例になります。 かわりに、こうしたプローブは、トレース・リクエストの終了のような、より抽象的な概念に使用されます。 その他のプロファイル・プロバイダやCPCプロバイダなどによって使用可能になるプローブも、その記述にモジュールや関数の識別子は含まれません。
Dプログラム
1つ以上のDTraceプローブに文と呼ばれる一連の処理命令をバインドできるため、プローブの起動時に指定の文を実行することで所要の機能を実行できます。 有効化されたプローブのセット、文、およびプローブの起動時に評価される可能性のある条件は、すべてDプログラムにまとめることができます。
プログラムは、どのプローブがDプログラム内の機能をトリガーできるかを決定する複数のプローブ記述で構成できます。 プローブ記述の後には、節と呼ばれる一連の処理命令が続きます。節には、選択したプローブの起動時に実行する内容を記述します。 述語と呼ばれる条件式は、プローブ記述と節の間に挿入することで、節内のアクションを実行する条件を制御できます。 たとえば、すべてのシステム・コールで起動して、特定のアプリケーションのシステム・コールをカウントするようにプログラムを設計できます。 このプログラムは、syscall:::entryプローブのプローブ記述、プロセスIDまたは実行可能ファイルの名前と一致するように処理を制限する述語、および各システム・コール関数に関する情報を収集するためにcount()関数を実行した節で構成されます。 その結果のDプログラムは、次のようになります:
/* Probe descriptions */
syscall:::entry
/* Predicate */
/execname=='date'/
/* Clause */
{
@reads[probefunc]=count();
}このスクリプトを実行すると、次のように、dateコマンドによって行われた各システム・コールが表示され、それぞれのカウント値が示されます。
dtrace: description 'syscall:::entry ' matched 344 probes
Wed 22 Feb 11:54:51 GMT 2023
exit_group 1
lseek 1
mmap 1
write 1
openat 2
read 2
brk 3
close 4
newfstat 4プログラムのプローブ記述は、エントリ・ポイントにあるすべてのシステム・コール関数と一致します。 プログラム述語は、演算子を使用して文字列に対して組込み変数のexecnameを評価します。 この節には、起動するプローブに関するデータの収集に使用される集積体の@readsが含まれます。 この場合、集積体には、プローブが起動され、述語が解決されるたびに増分するカウンタが格納されます。 カウンタは、count()関数によって実装され、システム・コール・プローブ関数ごとのカウント値を格納します。 プログラムの構造と構文の詳細は、「Dプログラム構文のリファレンス」を参照してください。
集積体
集積体を使用すると、大量のデータを、より小さく意味のある統計メトリックに縮小できます。 一連のデータを理解するために使用される一般的な機能の多くは、集計機能です。 こうした関数を次に示します。
-
セット内の要素数のカウント。
-
セットの最小値の計算。
-
セットの最大値の計算。
-
セット内のすべての要素の合計を計算します。
-
特定のビンに量子化されるように、セット内の値のヒストグラムを作成します。
データのセットに対して集計を計算するようにアプリケーションをコーディングすることもできますが、多数のプローブが同時に起動すると、集積変数に対する更新を相互に上書きすることや、計算がシリアル・ボトルネックになることがあります。
DTraceの集積関数は、トレース時にデータに適用されるため、データセットの格納が不要で、イベントの発生時にいつでも集積体が使用できます。 このようにすることで、集積関数はより効率的で正確なものになり、上書きを回避できます。 詳細は、「集積体」を参照してください。
投機
述語は対象外のイベントをフィルタ処理するために使用できますが、フィルタする必要があるイベントを事前に知っている場合にのみ役立ちます。 通常、DTraceは特定のシステム動作のデバッグに利用するため、DTraceにはデータの投機的なトレースに使用できる一連の投機関数が含まれています。
投機は、特定の情報が判明するまで一時的に定量をトレースするために使用され、その場合はデータを破棄することもコミットすることもできます。 投機トレースを実行することで、有用かどうかが判明するまでデータをトレースできます。 たとえば、特定のリターン・コードまたはエラーをトリガーする可能性のあるイベントに関するデータをトレースするために、すべてのイベントを投機的にトレースして、対象とするリターン・コードと一致しない場合はトレース・データを破棄できます。 詳細は、「投機」を参照してください。
バッファ
DTraceプローブが起動すると、カーネルは各種のバッファにデータを書き込みます。このバッファは、リクエストされたデータを出力するdtraceユーザー空間ユーティリティで読み取ります。
カーネルによるトレース・データの生成と、そのデータのdtraceユーティリティによる処理が非同期に実行されます。 トレース・データの処理は、バッファ・オプションとリフレッシュ率の設定で調整できます。 バッファ・サイズは、aggsize、bufsize、nspecなどのオプションで調整できます。
バッファ・サイズとポリシーを制御する各種のオプションについては、「DTraceの実行時オプションとコンパイル時オプションのリファレンス」を参照してください。
安定性
DTraceは、時間の経過によって変化する可能性のあるコードに含まれたプローブを利用するトレース・ツールです。 DTraceとDコンパイラには、作成するDプログラムの安定性を動的に計算して説明する機能があります。 こうしたDTraceの安定性機能を使用すると、Dプログラムの安定性属性を確認したり、プログラムに不適切なインタフェース依存関係があるときにコンパイル時エラーを生成できます。
DTraceには、組込み変数、関数、プローブなどのエンティティについて2種類の安定性属性が用意されています。その1つは安定性レベル、もう1つはアーキテクチャの依存クラスです。 DTraceの安定性レベルは、将来のリリースやパッチでインタフェースやDTraceエンティティが変更される可能性を示すことで、DTraceに基づいたスクリプトやツールの開発時にリスクを評価する際に役立ちます。 DTraceの依存クラスは、あるインタフェースがすべてのOracle Linuxプラットフォームとプロセッサに共通であるかどうか、あるいは特定のアーキテクチャに関連付けられいているかどうかを示します。 インタフェースの説明に使用される2つのタイプの属性は、それぞれ独立して異なる場合があります。
安定のインタフェースにのみ依存するアプリケーションは、今後のマイナー・リリースでも確実に機能を維持する可能性が高く、個別パッチによって破損する可能性は低くなります。 安定性の低いインタフェースは、現在のシステムでの実験、プロトタイプ作成、チューニングおよびデバッグに使用できます。 安定していないインタフェースは、将来のマイナー・リリースで変更されることや、互換性のない状態になること、削除されること、代替のインタフェースに置き換えられることを理解して使用してください。
インタフェースは、すべてのOracle Linuxプラットフォームとプロセッサに共通にすることも、特定のシステム・アーキテクチャに関連付けることもできます。 依存クラスは、アーキテクチャの依存関係を示すために役立ち、安定性レベルとは関係しません。 たとえば、DTraceインタフェースは安定であっても、x86_64マイクロプロセッサでのみ使用可能なこともあります。 また、インタフェースが不安定であっても、すべてのOracle Linuxプラットフォームに共通になることもあります。
ぞれぞれの安定性レベルと依存性クラスの詳細は、「DTrace安定性のリファレンス」を参照してください。