SystemTap01
[wiki:SystemTap00 SystemTap メモ #0] の続き。今回は SystemTap Beginners Guide の 3.2. SystemTap Scripts から抜粋。
スクリプトのフォーマット
SystemTap スクリプトのフォーマットはこんな感じ。
probe event { statements }
なので、[wiki:SystemTap00 前回] 出てきた、
$ stap -v -e 'probe vfs.read { printf("read performed\n"); exit() }'
をフォーマットと照らし合わせて読み解くと、*「vfs.read イベントが発生したら read performed と表示して exit する」*といった意味になる。
{ statements }_' の部分は '''handler''' と呼ばれ、'''event''' と それに対応した '''handler''' をあわせて '_probe と呼ぶらしい。
スクリプトの中では関数を定義して呼び出すこともできる。
function function_name(arguments) { statements }
probe event { function_name(arguments) }
イベント
イベントは同期イベントと非同期イベントに分かれる。
同期イベント
同期イベントはカーネルコード中の特定の場所で命令が実行された場合に発生するイベント。(非同期イベントは後で説明するが、命令実行とは関係なしに発生するイベント。)
同期イベントには以下のようなものがある。
syscall. ''''''system_call
system_call'' というシステムコールの呼び始めに発生するイベント。呼び終わりに発生するイベントは syscall.''system_call .return 。close システムコールの呼び始めに発生するイベントは syscall.close、呼び終わりに発生するイベントは syscall.close.return 。
vfs. ''''''file_operation
VFS に対して file_operation の呼び始めに発生するイベント。syscall と同様、 .return を付加すると、呼び終わりイベントとなる。
kernel.function(" ''''''function'''''' ")
カーネルファンクション function の呼び始めに発生するイベント。例えば kernel.function("sys_open") は sys_open の呼び始めに発生するイベント。.return がつくと呼び終わりイベント。ワイルドカードとして * がつかえる。また、以下のように特定のソースファイル中のファンクションも指定できる。
probe kernel.function("*@net/socket.c") { }
probe kernel.function("*@net/socket.c").return { }
kernel.trace(" ''''''tracepoint'''''' ")
カーネル内の特定のトレースポイントで発生するイベント。例えば、 kernel.trace("kfree_skb") だと、カーネル内のネットワークバッファが解放された時にイベントが発生する。
module(" ''''''module''''''''").function("''''''''function'''''' ")
モジュール内の特定のファンクションが呼ばれた場合に発生するイベント。
probe module("ext3").function("*") { }
probe module("ext3").function("*").return { }
この例だと、前者は ext3 モジュール内のすべてのファンクションの呼び始めに発生するイベント、後者は呼び終わりに発生するイベント、となる。
非同期イベント
非同期イベントはカーネルコード内の命令実行とは無関係に発生するイベント。以下のようなイベントがある。
begin
SystemTap セッションの開始時(SystemTap スクリプトの実行開始時)に発生するイベント。
end
SystemTap セッションの終了時に発生するイベント。
timer events
タイマーイベント。以下の例では4秒ごとにイベントを発生させる。
probe timer.s(4)
{
printf("hello world\n")
}
時間単位は上の例の秒以外にも、以下のように指定できる。
- timer.ms( milliseconds )
- timer.us( microseconds )
- timer.ns( nanoseconds )
- timer.hz( hertz )
- timer.jiffies( jiffies )
イベントは他にもたくさんあるので、詳しく知りたければ man stapprobes すべし。