第2章 タップセット開発ガイドライン

本章では、タップセットを適切に記録するアップストリームのガイドラインについて説明します。また、本ガイドで適切に定義されるよう、適切にタップセットを記録する方法も取り上げます。

2.1. タップセットの記述

適切なタップセットを記述するための最初のステップとして、主題の簡単なモデルを作成します。たとえば、プロセスサブシステムのモデルには以下が含まれます。
キーデータ

  • プロセス ID
  • 親プロセス ID
  • プロセスグループ ID

状態遷移

  • forked (フォーク)
  • exec'd (実行)
  • running (実行中)
  • stopped (停止)
  • terminated (終了)

注記

上記のリストは例であり、完全なリストではありません。
サブシステムの知識を活用して、モデルの要素を公開するプローブポイント (関数エントリーおよび終了) を見つけた後、これらのポイントのプローブエイリアスを定義します。複数の場所で発生する状態遷移があることに注意してください。このような場合、エイリアスはプローブを複数の場所に置くことができます。
たとえば、プロセス exec は do_execve() または compat_do_execve() 関数で発生させることができます。以下のエイリアスは、これらの関数の先頭にプローブを挿入します。
probe kprocess.exec = kernel.function("do_execve"),
kernel.function("compat_do_execve") 
{probe body}
プローブは可能な限り安定したインターフェースに置いてください (インターフェースレベルで変更されない関数など)。これにより、カーネルの変更によってタップセットが破損する可能性が低くなります。カーネルバージョンやアークテクチャーの依存関係を回避できない場合、プリプロセッサーの条件を使用します (詳細は stap(1) の man ページを参照してください)。
プローブポイントのキーデータをプローブボディーに追加します。関数エントリープローブは、関数に指定したエントリーパラメーターにアクセスできます。終了プローブは、エントリーパラメーターと戻り値にアクセスできます。適切な場合はデータを意味のある形式に変換します (バイトからキロバイト、状態値から文字列など)。
補助関数を使用して一部のデータにアクセスしたり、変換したりする必要がある場合があります。通常、補助関数は埋め込み C を使用して、コンテキストの構造フィールドへのアクセスやリストのリンク先への移動など、SystemTap 言語で実行できないことを行います。他のタップセットに定義された補助関数を使用したり、独自の補助関数を作成したりすることができます。
以下の例では、copy_process() は新しいプロセスの task_struct へのポインターを返します。task_pid() を呼び出し、task_struct ポインターへ渡すことで新しいプロセスのプロセス ID が取得されます。この場合、補助関数は task.stp に定義される埋め込み C 関数になります。
probe kprocess.create = kernel.function("copy_process").return 
{
   task = $return
   new_pid = task_pid(task)
}
すべての関数のプローブを作成することは推奨されません。ほとんどの SystemTap ユーザーはそれらを必要としたり、理解しておく必要はありません。簡単で高レベルなタップセットを作成するようにしてください。