第2章 tapset 開発ガイドライン
本章では、適切な tapset ドキュメントのアップストリームのガイドラインについて説明します。また、本ガイドで適切に定義されるように tapset を適切に記述する方法も含まれています。
2.1. tapset の記述
適切な tapset を記述するための最初の手順は、サブジェクトエリアの単純なモデルを作成することです。たとえば、プロセスサブシステムのモデルには以下が含まれる場合があります。
キーデータ
- プロセス ID
- 親プロセス ID
- プロセスグループ ID
状態遷移
- forked (フォーク)
- exec'd (実行)
- running (実行中)
- stopped (停止)
- terminated (終了)
注記
上記のリストは両方とも例であり、完全なリストではありません。
サブシステムの知識を使用して、モデルの要素を公開するプローブポイント (関数エントリーおよび終了) を検索し、それらのポイントのプローブエイリアスを定義します。一部の状態遷移は複数の場所で発生する可能性があることに注意してください。この場合、エイリアスはプローブを複数の場所に配置できます。
たとえば、プロセス実行は、関数
do_execve()
または compat_do_execve()
のいずれかで発生する可能性があります。以下のエイリアスは、これらの関数の最初にプローブを挿入します。
probe kprocess.exec = kernel.function("do_execve"), kernel.function("compat_do_execve") {probe body}
プローブを可能な限り安定したインターフェース (インターフェースレベルで変更できない関数など) に配置してみてください。これにより、カーネルの変更により tapset が破損する可能性が低くなります。カーネルのバージョンまたはアーキテクチャーの依存関係を回避できない場合は、プリプロセッサー条件を使用します (詳細は、man ページの
stap(1)
を参照してください)。
プローブポイントで利用可能なキーデータでプローブボディーを入力します。関数エントリープローブは、関数に指定されたエントリーパラメーターにアクセスできますが、終了プローブはエントリーパラメーターおよび戻り値にアクセスできます。適切な場合はデータを意味のある形式に変換します (バイトをキロバイト、状態値は文字列など)。
補助関数を使用して一部のデータにアクセスしたり、変換する必要がある場合があります。補助関数は多くの場合、埋め込み C を使用して SystemTap 言語では実行できないことを行います。たとえば、一部のコンテキスト内の構造フィールドへのアクセス、リンクされた一覧などです。他の tapset で定義された補助関数を使用するか、独自の tapset を作成することができます。
以下の例では、新しいプロセスに対して
task_struct
のポインターを copy_process()
に返します。新しいプロセスのプロセス ID は task_pid()
ポインターを呼び出して、task_struct
を渡すことで取得されます。この場合、補助関数は task.stp
で定義されている埋め込み C 関数です。
probe kprocess.create = kernel.function("copy_process").return { task = $return new_pid = task_pid(task) }
すべての関数にプローブを作成することは推奨されません。多くの SystemTap ユーザーには必要ありませんし、理解する必要もありません。簡単で高レベルな tapset を維持します。