SystemTap ビギナーズガイド
SystemTap 入門
概要
第1章 はじめに
1.1. 本ガイドの目的
- SystemTap の概要を紹介するほか、ユーザーにアーキテクチャーについて説明し、全カーネルタイプの設定手順を提供します。
- システムの異なるコンポーネントで詳細なアクティビティーを監視するための事前作成された SystemTap スクリプトを提供し、それらの実行方法と出力の分析方法も提供します。
1.2. SystemTap の機能
- 柔軟性 - SystemTap のフレームワークを使用すると、幅広いカーネル機能、システムコール、およびカーネルスペースで発生する他のイベントについて、調査および監視目的のシンプルなスクリプトを開発できます。つまり、SystemTap は ツール というよりも、独自のカーネル固有のフォレンジックおよび監視ツールの開発を可能にするシステムといえます。
- 容易な使用 - 上記で説明したように、SystemTap を使うことでユーザーはカーネルプロセスのインストルメント化、再コンパイル、インストール、および再起動という面倒なプロセスを経ずにカーネルスペースのイベントをプローブできるようになります。
第2章 SystemTap の使用
2.1. インストールと設定
2.1.1. SystemTap のインストール
root
として次のコマンドを実行して、systemtap および systemtap-runtime パッケージをインストールします。
~]#
yum install -y systemtap systemtap-runtime
2.1.2. 必要なカーネル情報パッケージのインストール
debug
リポジトリーから入手できます。
debug
リポジトリーを有効にします。
~]#
subscription-manager repos --enable=rhel-7-variant-debug-rpms
server
、workstation
、または client
に置き換えます。バリアントを特定するには、次のコマンドを使用できます。
~]#
cat /etc/redhat-release
Red Hat Enterprise Linux Server release 7.2 (Maipo)
uname -r
3.10.0-327.el7.x86_64
3.10.0-327.4.4.el7
で SystemTap を使用する場合は、次のパッケージをインストールする必要があります。
- kernel-debuginfo-3.10.0-327.4.4.el7.x86_64.rpm
- kernel-debuginfo-common-x86_64-3.10.0-327.4.4.el7.x86_64.rpm
- kernel-devel-3.10.0-327.4.4.el7.x86_64.rpm
root
として次のコマンドを実行します。
~]#
yum install -y kernel-devel-$(uname -r) \
kernel-debuginfo-$(uname -r) \
kernel-debuginfo-common-$(uname -m)-$(uname -r)
2.1.3. 初期テスト
stap -v -e 'probe vfs.read {printf("read performed\n"); exit()}'
read performed
を出力し、仮想ファイルシステムの読み取りが検出されたら、適切に終了するように、SystemTap に指示するだけです。SystemTap が正常にデプロイされていれば、以下のような出力になります。
Pass 1: parsed user script and 45 library script(s) in 340usr/0sys/358real ms. Pass 2: analyzed script: 1 probe(s), 1 function(s), 0 embed(s), 0 global(s) in 290usr/260sys/568real ms. Pass 3: translated to C into "/tmp/stapiArgLX/stap_e5886fa50499994e6a87aacdc43cd392_399.c" in 490usr/430sys/938real ms. Pass 4: compiled C into "stap_e5886fa50499994e6a87aacdc43cd392_399.ko" in 3310usr/430sys/3714real ms. Pass 5: starting run. read performed Pass 5: run completed in 10usr/40sys/73real ms.
Pass 5
で始まる) 出力の最後の 3 行は、SystemTap がカーネルをプローブするインストルメンテーションを正常に作成できたこと、インストルメンテーションを実行したこと、プローブしているイベントを検出したこと (このケースでは、仮想ファイルシステムの読み込み)、および有効なハンドラーを実行したこと (テキストを出力し、エラーなしで終了) を示しています。
2.2. 他のコンピューター用のインストルメンテーション生成
- 各種マシンのカーネル情報パッケージを単一のホストマシン にインストールできます。
- 生成された SystemTap インストルメンテーションモジュール (systemtap-runtime) を使用するには、ターゲットマシン ごとインストールする必要があるパッケージは 1 つだけです。
- インストルメンテーションモジュール
- SystemTap スクリプトから構築したカーネルモジュール。SystemTap モジュール は ホストシステム 上に構築され、ターゲットシステム の ターゲットカーネル に読み込まれます。
- ホストシステム
- ターゲットシステム に読み込めるように (SystemTap スクリプトから) インストルメンテーションモジュールをコンパイルするシステム。
- ターゲットシステム
- (SystemTap スクリプトから) インストルメンテーションモジュール を構築するシステム。
- ターゲットカーネル
- ターゲットシステム のカーネル。このカーネルが インストルメンテーションモジュール の読み込み、実行を行います。
手順2.1 ホストシステムとターゲットシステムの設定
- 各 ターゲットシステム に
systemtap-runtime
パッケージをインストールします。 - 各 ターゲットシステム で uname -r を実行して、各 ターゲットシステム で実行中のカーネルを確認します。
- SystemTap を ホストシステム にインストールします。インストルメンテーションモジュール は、ホストシステム 上で ターゲットシステム 用に構築されます。SystemTap のインストール方法については、「SystemTap のインストール」 を参照してください。
- 上記で判明した ターゲットカーネル のバージョンを使用して、ターゲットカーネル と関連パッケージを 「必要なカーネル情報パッケージのインストール」 に説明されている方法で ホストシステム にインストールします。複数の ターゲットシステム で異なる ターゲットカーネル を使用している場合は、ターゲットシステム で使用しているカーネルごとにこのステップを繰り返します。
stap -r kernel_version script -m module_name -p4
staprun module_name.ko
3.10.0-327.4.4.el7
ターゲットカーネル 用の simple.stp
という名前の SystemTap スクリプトから simple.ko
インストルメンテーションモジュール を作成するには、次のコマンドを使用します。
stap -r 2.6.32-53.el6 -e 'probe vfs.read {exit()}' -m simple -p4
simple.ko
という名前のモジュールが作成されます。インストルメンテーションモジュール simple.ko
を使用するには、これを ターゲットシステム にコピーして、(ターゲットシステム 上で) 以下のコマンドを実行します。
staprun simple.ko
2.3. SystemTap スクリプトの実行
root
アクセスを付与されるわけではありません。たとえば、権限のないユーザーが自身のマシン上で SystemTap インストルメンテーションを実行する必要がある場合もあります。
root
アクセスなしで SystemTap を実行できるようにするには、ユーザーを以下の両方のユーザーグループに追加します。
- stapdev
- このグループのメンバーは stap を使用して SystemTap スクリプトを実行したり、staprun を使用して SystemTap インストルメンテーションモジュールを実行したりできます。stap の実行では、SystemTap スクリプトがカーネルモジュールにコンパイルされ、それがカーネルに読み込まれます。これにはシステムに対する権限の昇格が必要となり、
stapdev
メンバーにはそれが付与されます。ただし、この権限はstapdev
メンバーに有効なroot
アクセスも付与することになります。このため、stapdev
グループのメンバーシップは、root
アクセスを信頼して付与できるメンバーにのみ許可してください。 - stapusr
- このグループのメンバーが SystemTap インストルメンテーションモジュールの実行に使用できるのは、staprun のみです。さらに、これらのモジュールは
/lib/modules/kernel_version/systemtap/
からのみ実行できます。このディレクトリーを所有できるのはroot
ユーザーのみで、書き込みが可能なのもroot
ユーザーのみでなければならない点に注意してください。
- -v
- SystemTap セッションの出力をさらに詳細なものにします。このオプション (たとえば、stap -vvv script.stp) を繰り返して、スクリプトの実行に関する詳細を提供できます。スクリプトの実行中にエラーが発生すると、これは特に便利なものになります。SystemTap スクリプトの一般的なエラーに関する詳細は、5章SystemTap のエラーを理解する を参照してください。
-o filename
- 標準出力を filename に送信します。
-S size、count
- ファイルのサイズを size で指定されたメガバイト数に制限し、ファイル数を count の数に制限します。ファイル名には、連続番号の接尾辞が付きます。このオプションは、SystemTap に logrotate 演算を実装します。
-o
とともに使用すると、-S
はログファイルのサイズを制限します。 -x process ID
-c command
- SystemTap ハンドラー関数の
target()
を指定されたコマンドに設定します。指定コマンドへの完全パスを使用する必要があります。たとえば、cp を指定する代わりに、(stap script -c/bin/cp のように) /bin/cp を使用します。target() の詳細については、SystemTap 関数 を参照してください。 -e 'script'
- systemtap 翻訳の入力に、ファイルではなく script 文字列を使用します。
-F
- SystemTap のフライトレコーダーモードを使用し、スクリプトをバックグラウンドプロセスにします。フライトレコーダーモードの詳細は、「SystemTap フライトレコーダーモード」 を参照してください。
-
スイッチを使用して標準入力からスクリプトを実行するように指示することもできます。例を示します。
例2.1 標準入力からスクリプトを実行
echo "probe timer.s(1) {exit()}" | stap -
echo "probe timer.s(1) {exit()}" | stap -v -
-v
および -o
も staprun で機能します。staprun の詳細については、staprun(1) man ページを参照してください。
2.3.1. SystemTap フライトレコーダーモード
-F
オプション) は、生成される出力の量を制限します。フライトレコーダーモードには、メモリー内モードとファイルモードの 2 種類があります。どちらの場合も、SystemTap スクリプトはバックグラウンドプロセスとして実行されます。
2.3.1.1. メモリー内フライトレコーダー
-F
オプション) をファイル名なしで使用すると、SystemTap はカーネルメモリー内のバッファーを使用してスクリプトの出力を保存します。次に、SystemTap インストルメンテーションモジュールが読み込まれてプローブの実行が開始し、インストルメンテーションが外されてバックグラウンドに置かれます。関心のあるイベントが発生すると、インストルメンテーションは再度アタッチされ、メモリーバッファー内の最近の出力と継続中の出力が閲覧可能となります。以下のコマンドでは、フライトレコーダーのメモリー内モードを使用してスクリプトが開始されます。
stap -F /usr/share/doc/systemtap-version/examples/io/iotime.stp
Disconnecting from systemtap module. To reconnect, type "staprun -A stap_5dd0073edcb1f13f7565d8c343063e68_19556"
staprun -A stap_5dd0073edcb1f13f7565d8c343063e68_19556
-s
オプションを使用してバッファーのメガバイト単位のサイズを指定する (2 の累乗に切り上げる) ことが可能です。たとえば、SystemTap コマンドライン上で -s2 とすると、バッファーを 2MB に指定します。
2.3.1.2. ファイルフライトレコーダー
-S
オプションにコンマ区切りの 2 つの数字の引数を続けて制御します。最初の引数は、各出力ファイルのメガバイト単位の最大サイズです。2 つ目の引数は、保存する最新ファイルの数です。ファイル名は、-o
オプションの後に名前を付けて指定します。SystemTap は数値の接尾辞をファイル名に付けてファイルの順序を示します。以下のコマンドでは、SystemTap がフライトレコーダーモードで開始され、出力は /tmp/pfaults.log.[0-9]+
という名前のファイルに保存されます。各ファイルのサイズは 1MB 以下となり、最新の 2 ファイルが保存されます。
stap -F -o /tmp/pfaults.log -S 1,2 pfaults.stp
SIGTERM
を送信すると、SystemTap スクリプトはシャットダウンし、データ収集が停止されます。たとえば、以前のコマンドでプロセス ID が 7590
となっている場合、以下のコマンドを実行すると SystemTap スクリプトはシャットダウンします。
kill -s SIGTERM 7590
1020K /tmp/pfaults.log.5 44K /tmp/pfaults.log.6
/tmp/pfaults.log.6
になります。
第3章 SystemTap の作動方法
3.1. アーキテクチャー
手順3.1 SystemTap セッション
- まず、SystemTap はスクリプトを既存のタップセットライブラリー (通常は
/usr/share/systemtap/tapset/
ディレクトリーにあります) に対してチェックし、使用されているタップセットを探します。次に SystemTap は、見つかった tapset を tapset ライブラリー内の対応する定義で置き換えます。 - SystemTap はスクリプトを C に変換し、システム C コンパイラーを実行してそこからカーネルモジュールを作成します。このステップを実行するツールは、systemtap パッケージに含まれています (詳細については、「SystemTap のインストール」 を参照)。
- SystemTap はモジュールを読み込み、スクリプト内の全プローブ (イベントおよびハンドラー) を有効にします。systemtap-runtime パッケージの staprun (詳細については、「SystemTap のインストール」 を参照) がこの機能を提供します。
- イベントが発生すると、それに対応するハンドラーが実行されます。
- SystemTap セッションが終了すると、プローブは無効になり、カーネルモジュールは読み込み解除されます。
3.2. SystemTap スクリプト
probe event {statements}
,
) で区切ります。1 つのプローブで複数のイベントが指定された場合、SystemTap は指定されたイベントが発生するとそのハンドラーを実行します。
function function_name(arguments){statements} probe event {function_name(arguments)}
3.2.1. イベント
- syscall.system_call
- システムコール system_call へのエントリー。システムコールの終了を希望する場合は、
.return
をイベントに追加すると、システムコールの終了を監視するようになります。たとえば、システムコールclose
のエントリーと終了を指定するには、syscall.close
およびsyscall.close.return
をそれぞれ使用します。 - vfs.file_operation
- 仮想ファイルシステム (VFS) の file_operation イベントへのエントリー。
syscall
イベントと同様に、イベントに.return
を追加すると、file_operation
動作の終了を監視します。 - kernel.function("function")
- カーネル関数
function
へのエントリー。たとえば、kernel.function("sys_open")
は、カーネル関数sys_open
がシステム内のスレッドによって呼び出される際に発生する イベント を参照します。カーネル関数sys_open
の return を指定するには、kernel.function("sys_open").return
のように、return
文字列をイベントステートメントに追加します。プローブイベントを定義する際には、アスタリスク (*
) をワイルドカードに使用できます。また、カーネルソースファイル内の関数のエントリーまたは終了も追跡可能です。以下の例を見てみましょう。例3.1 wildcards.stp
probe kernel.function("*@net/socket.c") { } probe kernel.function("*@net/socket.c").return { }
この例では、最初のプローブのイベントはnet/socket.c
カーネルソースファイル内の全関数のエントリーを指定しています。2 つ目のプローブでは、これら全関数の終了を指定しています。この例では、ハンドラーにステートメントがないことに注意してください。このため、情報が収集されず、表示されることもありません。 - kernel.trace("tracepoint")
- tracepoint の静的プローブ。最近のカーネル (2.6.30 以降) には、カーネル内の特定イベント用のインストルメンテーションが含まれています。これらのイベントは、トレースポイントで静的にマークが付けられています。SystemTap で利用可能なトレースポイントの例としては、
kernel.trace("kfree_skb")
があります。これは、カーネル内でネットワークバッファーが解放されると合図します。 - module("module").function("function")
- モジュール内の関数のプローブを可能にします。以下に例を示します。
例3.2 moduleprobe.stp
probe module("ext3").function("*") { } probe module("ext3").function("*").return { }
例3.2「moduleprobe.stp」 の最初のプローブは、ext3
モジュールの 全 関数のエントリーを指しています。2 つ目のプローブは、同じモジュールの全関数の終了を指しています。.return
の接尾辞の使用は、kernel.function()
と類似します。例3.2「moduleprobe.stp」 のプローブは、プローブハンドラーにステートメントがないことに注意してください。このため、有用なデータは出力されません (例3.1「wildcards.stp」 の場合と同様)。システムのカーネルモジュールは通常、/lib/modules/kernel_version
にあります。ここで、kernel_version は現在ロードされているカーネルバージョンを指します。モジュールは、ファイル名拡張子.ko
を使用します。
- begin
- SystemTap スクリプトの実行と同時に、SystemTap セッションが起動します。
- end
- SystemTap セッションが終了します。
- timer イベント
- ハンドラーの定期実行を指定するイベントです。以下に例を示します。
例3.3 timer-s.stp
probe timer.s(4) { printf("hello world\n") }
例3.3「timer-s.stp」 は、4 秒ごとにhello world
を出力するプローブの例です。以下のような timer イベントも使用できます。timer.ms(milliseconds)
timer.us(microseconds)
timer.ns(nanoseconds)
timer.hz(hertz)
timer.jiffies(jiffies)
情報を収集する他のプローブと併せて timer イベントを使用すると、定期的な更新を出力でき、その情報の変遷が分かります。
3.2.2. Systemtap ハンドラー/ボディー
例3.4 helloworld.stp
probe begin { printf ("hello world\n") exit () }
begin
イベント (セッションの開始) が { }
で囲まれているハンドラーを始動させます。これは単に hello world
を出力して改行し、終了するものです。
printf ( ) ステートメント
printf()
ステートメントは、データを出力するための最も単純な関数の一つです。printf()
は、次の形式で多くの SystemTap 関数を使用してデータを表示するためにも使用できます。
printf ("format string\n", arguments)
hello world
の出力を指示するだけで、書式指定子は含みません。
%s
(文字列用) や %d
(数字用) といった書式指定子を書式文字列に使用することもできます。書式文字列には複数の書式指定子を使用することが可能で、それぞれを対応する引数に一致させます。複数の引数はコンマ (,
) で区切ります。
例3.5 variables-in-printf-statements.stp
probe syscall.open { printf ("%s(%d) open\n", execname(), pid()) }
open
への全エントリーをプローブするように指示しています。各イベントでは、現行の execname()
(実行可能ファイル名の付いた文字列) と pid()
(現行のプロセス ID 番号) に続けて open
という単語を出力します。このプローブ出力の抜粋は以下のようになります。
vmware-guestd(2206) open hald(2360) open hald(2360) open hald(2360) open df(3433) open df(3433) open df(3433) open hald(2360) open
SystemTap 関数
SystemTap は、printf()
引数として使用できる多くの機能をサポートしています。例3.5「variables-in-printf-statements.stp」 は、SystemTap 関数 execname()
(カーネル関数を呼び出した/システムコールを実行したプロセスの名前) および pid()
(現在のプロセス ID) を使用します。
- tid()
- 現行スレッドの ID。
- uid()
- 現行ユーザーの ID。
- cpu()
- 現行の CPU 番号。
- gettimeofday_s()
- Unix epoch (1970 年 1 月 1 日) からの秒数。
- ctime()
- UNIX epoch からの秒数を日にちに換算。
- pp()
- 現在処理されているプローブポイントを記述する文字列。
- thread_indent()
- この関数は出力結果をうまく整理するので、便利なものです。この関数はインデント差分の引数を取ります。これは、スレッドのインデントカウンターに追加する、またはそこから取り除くスペースの数を示すものです。その後、適切なインデントスペースの数と一般的な追跡データの文字列を返します。ここで返された文字列の一般的なデータに含まれるのは、タイムスタンプ (スレッドの
thread_indent()
への最初の呼び出しからのマイクロ秒)、プロセス名、およびスレッド ID です。これによりどの関数が呼び出されたか、誰が呼び出したか、各関数呼び出しの長さが特定できます。それぞれの呼び出しが終わり次第、次の呼び出しが始まれば、エントリーと終了の一致は容易です。ただし、ほとんどの場合は、最初の関数呼び出しエントリーがなされた後、これが終了する前に他の複数の呼び出しがエントリーおよび終了することがあります。インデントカウンターがあることで、最初の呼び出しが終了していない場合、次の関数呼び出しをインデントして、エントリーとそれに対応する終了が一致しやすくなります。以下でthread_indent()
の使用例を見てみましょう。例3.6 thread_indent.stp
probe kernel.function("*@net/socket.c") { printf ("%s -> %s\n", thread_indent(1), probefunc()) } probe kernel.function("*@net/socket.c").return { printf ("%s <- %s\n", thread_indent(-1), probefunc()) }
0 ftp(7223): -> sys_socketcall 1159 ftp(7223): -> sys_socket 2173 ftp(7223): -> __sock_create 2286 ftp(7223): -> sock_alloc_inode 2737 ftp(7223): <- sock_alloc_inode 3349 ftp(7223): -> sock_alloc 3389 ftp(7223): <- sock_alloc 3417 ftp(7223): <- __sock_create 4117 ftp(7223): -> sock_create 4160 ftp(7223): <- sock_create 4301 ftp(7223): -> sock_map_fd 4644 ftp(7223): -> sock_map_file 4699 ftp(7223): <- sock_map_file 4715 ftp(7223): <- sock_map_fd 4732 ftp(7223): <- sys_socket 4775 ftp(7223): <- sys_socketcall
この出力サンプルには、以下の情報が含まれています。- スレッドの最初の
thread_indent()
呼び出しからの時間 (マイクロ秒単位)。 - 関数呼び出しを行ったプロセス名 (およびそれに対応する ID)。
- 呼び出しがエントリー (
<-
) か終了 (->
) かを示す矢印。インデントがあることで、特定の関数呼び出しのエントリーとそれに対応する終了が一致しやすくなります。 - プロセスが呼び出した関数名。
- name
- 特定のシステムコールの名前を識別します。この変数は、イベント syscall.system_call を使用するプローブでのみ使用できます。
- target()
- 次の 2 つのコマンドのいずれかと組み合わせて使用します。
stap script -x process ID stap script -c command
プロセス ID またはコマンドの引数を取るスクリプトを指定したい場合、スクリプト内で参照先となる変数としてtarget()
を使用します。以下に例を示します。例3.7 targetexample.stp
probe syscall.* { if (pid() == target()) printf("%s/n", name) }
例3.7「targetexample.stp」 を引数-x process ID
で実行すると、(syscall.*
イベントで指定された) すべてのシステムコールを監視し、指定されたプロセスで実行された全システムコールの名前を出力します。これは、特定のプロセスをターゲットとしたい場合に毎回if (pid() == process ID)
と指定することと同様の効果があります。ただし、target()
を使用すると、スクリプトの再利用が容易になり、スクリプトを実行するたびに引数としてプロセス ID を渡すだけで済みます。以下に例を示します。stap targetexample.stp -x process ID
3.3. 基本的な SystemTap ハンドラーコンストラクト
3.3.1. 変数
var
を gettimeofday_s()
に (var = gettimeofday_s()
のように) 設定すると、var
は数字として識別され、printf()
では整数の書式指定子 (%d
) で出力されます。
global
を使用して変数名を宣言します。以下の例を見てみましょう。
例3.8 timer-jiffies.stp
global count_jiffies, count_ms probe timer.jiffies(100) { count_jiffies ++ } probe timer.ms(100) { count_ms ++ } probe timer.ms(12345) { hz=(1000*count_jiffies) / count_ms printf ("jiffies:ms ratio %d:%d => CONFIG_HZ=%d\n", count_jiffies, count_ms, hz) exit () }
CONFIG_HZ
設定を計算し、それに応じて計算しています。global
ステートメントにより、スクリプトは変数 count_jiffies
および count_ms
(各プローブで設定) を probe timer.ms(12345)
と共有して使用することができます。
++
表記 (count_jiffies ++
と count_ms ++
) は、変数の値を 1 増やすために使用されます。以下のプローブで count_jiffies
は、100 jiffies ごとに 1 つ増えます。
probe timer.jiffies(100) { count_jiffies ++ }
count_jiffies
が整数であると理解します。count_jiffies
には初期値が割り当てられていないことから、デフォルトでは初期値はゼロになります。
3.3.2. 条件付き (conditional) ステートメント
- If/Else ステートメント
- 書式は以下のようになります。
if (condition) statement1 else statement2
condition
式がゼロ以外の場合、statement1
が実行されます。condition
式がゼロの場合、statement2
が実行されます。else
節 (else
statement2) はオプションです。statement1
とstatement2
は両方とも、ステートメントブロックになります。例3.9 ifelse.stp
global countread, countnonread probe kernel.function("vfs_read"),kernel.function("vfs_write") { if (probefunc()=="vfs_read") countread ++ else countnonread ++ } probe timer.s(5) { exit() } probe end { printf("VFS reads total %d\n VFS writes total %d\n", countread, countnonread) }
例3.9「ifelse.stp」 は、5 秒間にシステムが実行する仮想ファイルシステムの読み込み (vfs_read
) と書き込み (vfs_write
) 回数をカウントするスクリプトです。この実行時には、プローブした関数の名前が (条件if (probefunc()=="vfs_read")
に記してあるように)vfs_read
と一致する場合、スクリプトは変数countread
の値を 1 つ増やします。一致しない場合は、countnonread
(else {countnonread ++}
) を増やします。 - While ループ
- 書式は以下のようになります。
while (condition) statement
condition
がゼロ以外であれば、statement
内のステートメントのブロックは実行されます。statement
はステートメントブロックであることが多く、condition
が最終的にゼロとなるように値を変更する必要があります。 - For ループ
- 書式は以下のようになります。
for (initialization; conditional; increment) statement
for
ループは、単に while ループの短縮形です。以下が同等のwhile
ループになります。initialization while (conditional) { statement increment }
- >=
- より大か等しい
- <=
- より小か等しい
- !=
- 等しくない
3.3.3. コマンドラインの引数
$
または @
の直後にコマンドライン上の引数の番号を続けることで、単純なコマンドライン引数を受け付けるようにすることができます。コマンドライン引数としてユーザーが整数を入力すると思われる場合は $
を、文字列が予測される場合は @
を使用します。
例3.10 commandlineargs.stp
probe kernel.function(@1) { } probe kernel.function(@1).return { }
@1
、@2
のように、ユーザーが入力した順番で複数のコマンドライン引数をスクリプトが受け付けるように指定することもできます。
3.4. 連想アレイ
global
変数として宣言されるべきです。連想アレイ内の要素にアクセスする構文は awk の構文と似ており、以下のようになります。
array_name[index_expression]
array_name
は、アレイが使用する任意の名前です。index_expression
は、アレイ内の特定の一意のキーを見るために使用されます。例として、tom
、dick
、および harry
という 3 人の年齢 (一意のキー) を指定する、arr
という名前のアレイを構築してみましょう。それらにそれぞれ 23、24、および 25 の年齢 (関連付けられた値) を割り当てるには、次のアレイステートメントを使用します。
例3.11 基本的なアレイステートメント
arr["tom"] = 23 arr["dick"] = 24 arr["harry"] = 25
,
) で区切ります。これは、キーに複数の情報が含まれる場合に便利です。例4.9「disktop.stp」 からの以下の行では、プロセス ID、実行可能ファイル名、ユーザー ID、親プロセスの ID、および文字列 W という 5 つの要素を使用しています。ここでは、devname
の値をキーに関連付けています。
device[pid(),execname(),uid(),ppid(),"W"] = devname
global
と宣言する必要があります。
3.5. SystemTap でのアレイ演算
3.5.1. 関連する値の割り当て
=
を使います。
array_name[index_expression] = value
index_expression
と value
の両方に、ハンドラー関数を使用することもできます。たとえば以下のように、アレイを使用して、タイムスタンプをプロセス名 (これを一意のキーとして使用) への関連する値として設定することができます。
例3.12 タイムスタンプをプロセス名に関連付ける
arr[tid()] = gettimeofday_s()
tid()
値 (つまり、スレッドの ID。これは一意のキーとして使用されます) を返します。同時に SystemTap は関数 gettimeofday_s()
を使用して、対応するタイムスタンプを関数 tid()
で定義されている一意のキーへの関連する値として設定します。これで、スレッド ID とタイムスタンプを含むキーのペアで設定されるアレイが作成されます。
tid()
がアレイ arr
ですでに定義されている値を返すと、この演算子はその値に関連付けられている元の値を破棄し、gettimeofday_s()
からの現行タイムスタンプで置き換えます。
3.5.2. アレイからの値の読み取り
array_name[index_expression]
ステートメントを数式に要素として含めます。以下に例を示します。
例3.13 単純計算でのアレイ値の使用
delta = gettimeofday_s() - arr[tid()]
arr
が構築されていることを想定しています。これで 参照ポイント となるタイムスタンプが設定され、delta
の計算に使用されます。
gettimeofday_s()
からキー tid()
の関連する値を差し引くことで、変数 delta
の値を計算します。このコンストラクトは、tid()
の値をアレイから 読み取る ことで計算を行います。このコンストラクトは、読み取り操作の開始と完了など、2 つのイベント間の時間を判定する際に便利なものです。
index_expression
が一意のキーを見つけられない場合は、0 の値 (例3.13「単純計算でのアレイ値の使用」 などの数値演算の場合) もしくは null (空) の文字列の値 (文字列の演算の場合) がデフォルトで返されます。
3.5.3. 関連する値の増加
++
を使用します。
array_name[index_expression] ++
index_expression
にハンドラー関数を使用できます。たとえば、仮想ファイルシステムへの読み込み (vfs.read
イベントを使用) を特定のプロセスが実行した回数を計算したい場合は、以下のプローブを使用します。
例3.14 vfsreads.stp
probe vfs.read { reads[execname()] ++ }
gnome-terminal
に関連する値 1 が付いたものになります。プローブがプロセス名 gnome-terminal を次に返す際には、SystemTap は gnome-terminal
の関連する値を 1 増やします。SystemTap は、プローブがプロセス名を返す際にこの演算を すべての プロセス名に対して実行します。
3.5.4. アレイ内での複数要素の処理
reads
アレイでキーのペアを出力することです。
foreach
ステートメントを使用することです。以下の例を見てみましょう。
例3.15 cumulative-vfsreads.stp
global reads probe vfs.read { reads[execname()] ++ } probe timer.s(3) { foreach (count in reads) printf("%s : %d \n", count, reads[count]) }
foreach
ステートメントが count
変数を使用して reads
アレイ内の一意のキーの反復を参照しています。同じプローブ内の reads[count]
アレイステートメントは、一意のキーの関連する値を取得します。
foreach
ステートメントは、順不同でアレイ内のプロセス名の 全 反復を出力することに注意してください。+
(昇順) または -
(降順) を使用すると、スクリプトに特定の順番で反復をプロセスするよう指示することができます。さらに、limit value
オプションを使うと、スクリプトがプロセスする反復数を制限することもできます。
probe timer.s(3) { foreach (count in reads- limit 10) printf("%s : %d \n", count, reads[count]) }
foreach
ステートメントは、スクリプトにアレイ reads
内の要素を (関連する値の) 降順で処理するよう指示します。limit 10
オプションは、foreach
に最初の 10 の反復のみを処理するよう指示します (つまり、値の高い上位 10 位の反復のみを出力します)。
3.5.5. アレイおよびアレイ要素の消去/削除
delete
演算子を使用してアレイ内の要素またはアレイ全体を削除すると、これが実行できます。以下の例を見てみましょう。
例3.16 noncumulative-vfsreads.stp
global reads probe vfs.read { reads[execname()] ++ } probe timer.s(3) { foreach (count in reads) printf("%s : %d \n", count, reads[count]) delete reads }
delete reads
ステートメントは、プローブ内の reads
アレイを消去します。
global reads, totalreads probe vfs.read { reads[execname()] ++ totalreads[execname()] ++ } probe timer.s(3) { printf("=======\n") foreach (count in reads-) printf("%s : %d \n", count, reads[count]) delete reads } probe end { printf("TOTALS\n") foreach (total in totalreads-) printf("%s : %d \n", total, totalreads[total]) }
reads
と totalreads
のアレイが同じ情報を追跡し、同様の方式で出力します。唯一の違いは、reads
は 3 秒ごとに消去されるのに対して、totalreads
は増え続けるという点です。
3.5.6. 条件付きステートメントにおけるアレイの使用
if
ステートメントでも使用することができます。これは、アレイ内の値が特定の条件に一致した場合にサブルーチンを実行するという場合に便利です。以下の例を見てみましょう。
例3.17 vfsreads-print-if-1kb.stp
global reads probe vfs.read { reads[execname()] ++ } probe timer.s(3) { printf("=======\n") foreach (count in reads-) if (reads[count] >= 1024) printf("%s : %dkB \n", count, reads[count]/1024) else printf("%s : %dB \n", count, reads[count]) }
if
ステートメントがこれを変換し、kB
で出力します。
if([index_expression] in array_name) statement
例3.18 vfsreads-stop-on-stapio2.stp
global reads probe vfs.read { reads[execname()] ++ } probe timer.s(3) { printf("=======\n") foreach (count in reads+) printf("%s : %d \n", count, reads[count]) if(["stapio"] in reads) { printf("stapio read detected, exiting\n") exit() } }
if(["stapio"] in reads)
ステートメントは、一意のキー stapio
がアレイ reads
に追加されたら、stapio read detected, exiting
を出力するようにスクリプトに指示します。
3.5.7. 統計集計の計算
<<< value
を使用します。
例3.19 stat-aggregates.stp
global reads probe vfs.read { reads[execname()] <<< count }
<<< count
が、reads
アレイ内の対応する execname()
の関連する値に count
が返した数字を 保存 します。これらの値は 保存される のであって、各一意のキーの関連する値に追加されたり、現行の関連する値に置き換わるものではありません。各一意のキー (execname()
) に複数の関連する値があり、ハンドラーが実行するプローブで累積していると考えればよいでしょう。
@extractor(variable/array index expression)
を使用します。extractor
は次の整数抽出のいずれかです。
- count
- 変数やアレイのインデックス式に保存されたすべての値の数を返します。例3.19「stat-aggregates.stp」 のサンプルプローブでは、
@count(writes[execname()])
の式は、アレイwrites
の各一意のキーに 保存されている値の数 を返します。 - sum
- 変数やアレイのインデックス式に保存されたすべての値の合計を返します。例3.19「stat-aggregates.stp」 のサンプルプローブでは、
@sum(writes[execname()])
の式は、アレイwrites
の各一意のキーに 保存されている値すべての合計 を返します。 - min
- 変数やアレイのインデックス式に保存されたすべての値で最も小さいものを返します。
- max
- 変数やアレイのインデックス式に保存されたすべての値で最も大きいものを返します。
- avg
- 変数やアレイのインデックス式に保存されたすべての値の平均を返します。
例3.20 複数のアレイインデックス
global reads probe vfs.read { reads[execname(),pid()] <<< 1 } probe timer.s(3) { foreach([var1,var2] in reads) printf("%s (%d) : %d \n", var1, var2, @count(reads[var1,var2])) }
reads
が収集した情報を処理して出力する方法を示しています。foreach
ステートメントは、最初のプローブのアレイ reads
の最初のインスタンスに含まれる変数 (var1
および var2
) と同じ数を使用している点に注意してください。
3.6. Tapsets
.stp
を使用します。タップセットの標準ライブラリーは、デフォルトで /usr/share/systemtap/tapset/
ディレクトリーにあります。ただし SystemTap スクリプトとは異なり、tapsets は直接実行するものではなく、他のスクリプトがそこから定義をプルできるライブラリーを設定します。
thread_indent()
は indent.stp
で定義されています。
第4章 便利な SystemTap スクリプト
/usr/share/systemtap/testsuite/systemtap.examples/
ディレクトリーで使用できます。
4.1. ネットワーク
4.1.1. ネットワークのプロファイリング
例4.1 nettop.stp
#! /usr/bin/env stap global ifxmit, ifrecv global ifmerged probe netdev.transmit { ifxmit[pid(), dev_name, execname(), uid()] <<< length } probe netdev.receive { ifrecv[pid(), dev_name, execname(), uid()] <<< length } function print_activity() { printf("%5s %5s %-7s %7s %7s %7s %7s %-15s\n", "PID", "UID", "DEV", "XMIT_PK", "RECV_PK", "XMIT_KB", "RECV_KB", "COMMAND") foreach ([pid, dev, exec, uid] in ifrecv) { ifmerged[pid, dev, exec, uid] += @count(ifrecv[pid,dev,exec,uid]); } foreach ([pid, dev, exec, uid] in ifxmit) { ifmerged[pid, dev, exec, uid] += @count(ifxmit[pid,dev,exec,uid]); } foreach ([pid, dev, exec, uid] in ifmerged-) { n_xmit = @count(ifxmit[pid, dev, exec, uid]) n_recv = @count(ifrecv[pid, dev, exec, uid]) printf("%5d %5d %-7s %7d %7d %7d %7d %-15s\n", pid, uid, dev, n_xmit, n_recv, n_xmit ? @sum(ifxmit[pid, dev, exec, uid])/1024 : 0, n_recv ? @sum(ifrecv[pid, dev, exec, uid])/1024 : 0, exec) } print("\n") delete ifxmit delete ifrecv delete ifmerged } probe timer.ms(5000), end, error { print_activity() }
print_activity()
関数は、以下の式を使用する点に注意してください。
n_xmit ? @sum(ifxmit[pid, dev, exec, uid])/1024 : 0 n_recv ? @sum(ifrecv[pid, dev, exec, uid])/1024 : 0
if
または else
条件分岐です。2 番目のステートメントは、次の疑似コードをより簡潔に記述したものです。
if n_recv != 0 then @sum(ifrecv[pid, dev, exec, uid])/1024 else 0
PID
— 一覧表示されているプロセスの ID。UID
— ユーザー ID。ユーザー ID が0
の場合は、root ユーザーを指します。DEV
— データの送受信に使用されるイーサネットデバイス (eth0、eth1 など)。XMIT_PK
— プロセスが送信したパケット数。RECV_PK
— プロセスが受信したパケット数。XMIT_KB
— プロセスが送信したデータ量 (キロバイト単位)。RECV_KB
— サービスが受信したデータ量 (キロバイト単位)。
probe timer.ms(5000)
を適切に編集すると、変更できます。例4.2「例4.1「nettop.stp」 出力サンプル」 には、例4.1「nettop.stp」 からの 20 秒間の出力の抜粋が含まれています。
例4.2 例4.1「nettop.stp」 出力サンプル
[...] PID UID DEV XMIT_PK RECV_PK XMIT_KB RECV_KB COMMAND 0 0 eth0 0 5 0 0 swapper 11178 0 eth0 2 0 0 0 synergyc PID UID DEV XMIT_PK RECV_PK XMIT_KB RECV_KB COMMAND 2886 4 eth0 79 0 5 0 cups-polld 11362 0 eth0 0 61 0 5 firefox 0 0 eth0 3 32 0 3 swapper 2886 4 lo 4 4 0 0 cups-polld 11178 0 eth0 3 0 0 0 synergyc PID UID DEV XMIT_PK RECV_PK XMIT_KB RECV_KB COMMAND 0 0 eth0 0 6 0 0 swapper 2886 4 lo 2 2 0 0 cups-polld 11178 0 eth0 3 0 0 0 synergyc 3611 0 eth0 0 1 0 0 Xorg PID UID DEV XMIT_PK RECV_PK XMIT_KB RECV_KB COMMAND 0 0 eth0 3 42 0 2 swapper 11178 0 eth0 43 1 3 0 synergyc 11362 0 eth0 0 7 0 0 firefox 3897 0 eth0 0 1 0 0 multiload-apple [...]
4.1.2. ネットワークソケットコードで呼び出された関数の追跡
net/socket.c
ファイルから呼び出された関数を追跡する方法について説明します。このタスクでは、各プロセスがカーネルレベルでネットワークと対話する様子が詳細に分かります。
例4.3 socket-trace.stp
#!/usr/bin/stap probe kernel.function("*@net/socket.c").call { printf ("%s -> %s\n", thread_indent(1), probefunc()) } probe kernel.function("*@net/socket.c").return { printf ("%s <- %s\n", thread_indent(-1), probefunc()) }
thread_indent()
が機能する様子を説明するために SystemTap 関数 で使用されました。
例4.4 例4.3「socket-trace.stp」 出力サンプル
[...] 0 Xorg(3611): -> sock_poll 3 Xorg(3611): <- sock_poll 0 Xorg(3611): -> sock_poll 3 Xorg(3611): <- sock_poll 0 gnome-terminal(11106): -> sock_poll 5 gnome-terminal(11106): <- sock_poll 0 scim-bridge(3883): -> sock_poll 3 scim-bridge(3883): <- sock_poll 0 scim-bridge(3883): -> sys_socketcall 4 scim-bridge(3883): -> sys_recv 8 scim-bridge(3883): -> sys_recvfrom 12 scim-bridge(3883):-> sock_from_file 16 scim-bridge(3883):<- sock_from_file 20 scim-bridge(3883):-> sock_recvmsg 24 scim-bridge(3883):<- sock_recvmsg 28 scim-bridge(3883): <- sys_recvfrom 31 scim-bridge(3883): <- sys_recv 35 scim-bridge(3883): <- sys_socketcall [...]
thread_indent()
が提供するこのスクリプトの出力に関する詳細情報は、SystemTap 関数 例3.6「thread_indent.stp」 を参照してください。
4.1.3. 着信 TCP 接続の監視
例4.5 tcp_connections.stp
#! /usr/bin/env stap probe begin { printf("%6s %16s %6s %6s %16s\n", "UID", "CMD", "PID", "PORT", "IP_SOURCE") } probe kernel.function("tcp_accept").return?, kernel.function("inet_csk_accept").return? { sock = $return if (sock != 0) printf("%6d %16s %6d %6d %16s\n", uid(), execname(), pid(), inet_get_local_port(sock), inet_get_ip_source(sock)) }
- 現在の
UID
CMD
- 接続を受け付けるコマンド- そのコマンドの
PID
- 接続が使用するポート
- TCP 接続の発信元となる IP アドレス
例4.6 例4.5「tcp_connections.stp」 出力サンプル
UID CMD PID PORT IP_SOURCE 0 sshd 3165 22 10.64.0.227 0 sshd 3165 22 10.64.0.227
4.1.4. カーネルでのネットワークパケットドロップの監視
kernel.trace("kfree_skb")
が含まれています。例4.7「dropwatch.stp」 は、kernel.trace("kfree_skb")
を使用して、パケットの破棄を追跡します。スクリプトは、5 秒間隔ごとにパケットを破棄する場所を要約します。
例4.7 dropwatch.stp
#!/usr/bin/stap ############################################################ # Dropwatch.stp # Author: Neil Horman <nhorman@redhat.com> # An example script to mimic the behavior of the dropwatch utility # http://fedorahosted.org/dropwatch ############################################################ # Array to hold the list of drop points we find global locations # Note when we turn the monitor on and off probe begin { printf("Monitoring for dropped packets\n") } probe end { printf("Stopping dropped packet monitor\n") } # increment a drop counter for every location we drop at probe kernel.trace("kfree_skb") { locations[$location] <<< 1 } # Every 5 seconds report our drop locations probe timer.sec(5) { printf("\n") foreach (l in locations-) { printf("%d packets dropped at location %p\n", @count(locations[l]), l) } delete locations }
kernel.trace("kfree_skb")
は、カーネル内でネットワークパケットがドロップした場所を追跡します。kernel.trace("kfree_skb")
には、解放されているバッファーへのポインター ($skb
) と、解放されているバッファーのカーネルコード内での場所 ($location
) という 2 つの引数があります。
例4.8 例4.7「dropwatch.stp」 出力サンプル
Monitoring for dropped packets 51 packets dropped at location 0xffffffff8024cd0f 2 packets dropped at location 0xffffffff8044b472 51 packets dropped at location 0xffffffff8024cd0f 1 packets dropped at location 0xffffffff8044b472 97 packets dropped at location 0xffffffff8024cd0f 1 packets dropped at location 0xffffffff8044b472 Stopping dropped packet monitor
/boot/System.map-$(uname -r)
ファイルを参照してください。このファイルには、各関数の開始アドレスが記載されており、例4.8「例4.7「dropwatch.stp」 出力サンプル」 の出力のアドレスを特定の関数名にマップできます。次の /boot/System.map-$(uname -r)
ファイルのスニペットを考えると、アドレス 0xffffffff8024cd0f が関数 unix_stream_recvmsg
にマップされます。また、アドレス 0xffffffff8044b472 は関数 arp_rcv
にマップされます。
[...] ffffffff8024c5cd T unlock_new_inode ffffffff8024c5da t unix_stream_sendmsg ffffffff8024c920 t unix_stream_recvmsg ffffffff8024cea1 t udp_v4_lookup_longway [...] ffffffff8044addc t arp_process ffffffff8044b360 t arp_rcv ffffffff8044b487 t parp_redo ffffffff8044b48c t arp_solicit [...]
4.2. ディスク
4.2.1. ディスク読み取り/書き込みトラフィックの要約
例4.9 disktop.stp
#!/usr/bin/stap # # Copyright (C) 2007 Oracle Corp. # # Get the status of reading/writing disk every 5 seconds, # output top ten entries # # This is free software,GNU General Public License (GPL); # either version 2, or (at your option) any later version. # # Usage: # ./disktop.stp # global io_stat,device global read_bytes,write_bytes probe vfs.read.return { if ($return>0) { if (devname!="N/A") {/*skip read from cache*/ io_stat[pid(),execname(),uid(),ppid(),"R"] += $return device[pid(),execname(),uid(),ppid(),"R"] = devname read_bytes += $return } } } probe vfs.write.return { if ($return>0) { if (devname!="N/A") { /*skip update cache*/ io_stat[pid(),execname(),uid(),ppid(),"W"] += $return device[pid(),execname(),uid(),ppid(),"W"] = devname write_bytes += $return } } } probe timer.ms(5000) { /* skip non-read/write disk */ if (read_bytes+write_bytes) { printf("\n%-25s, %-8s%4dKb/sec, %-7s%6dKb, %-7s%6dKb\n\n", ctime(gettimeofday_s()), "Average:", ((read_bytes+write_bytes)/1024)/5, "Read:",read_bytes/1024, "Write:",write_bytes/1024) /* print header */ printf("%8s %8s %8s %25s %8s %4s %12s\n", "UID","PID","PPID","CMD","DEVICE","T","BYTES") } /* print top ten I/O */ foreach ([process,cmd,userid,parent,action] in io_stat- limit 10) printf("%8d %8d %8d %25s %8s %4s %12d\n", userid,process,parent,cmd, device[process,cmd,userid,parent,action], action,io_stat[process,cmd,userid,parent,action]) /* clear data */ delete io_stat delete device read_bytes = 0 write_bytes = 0 } probe end{ delete io_stat delete device delete read_bytes delete write_bytes }
UID
— ユーザー ID。ユーザー ID が0
の場合は、root ユーザーを参照します。PID
— 一覧表示されているプロセスの ID。PPID
— 一覧表示されているプロセスの 親プロセス のプロセス ID。CMD
— 一覧表示されているプロセスの名前。DEVICE
— 一覧表示されているプロセスが、読み取りまたは書き込みを行っているストレージデバイス。T
— プロセスが実行したアクションのタイプ。W
は書き込みを、R
は読み取りを指します。BYTES
— ディスクに対して読み書きされるデータの量。
ctime()
とgettimeofday_s()
によって戻されます。ctime()
は Unix 時間の開始 (1970 年 1 月 1 日) からの経過秒数でカレンダー時間を導出します。gettimeofday_s()
は Unix 時間の開始からの 実際 の秒数をカウントします。これにより、人間が判読できるかなり正確な出力のタイムスタンプが得られます。
$return
は各プロセスが仮想ファイルシステムから読み書きする実際のバイト数を保存するローカル変数です。$return
は、return プローブ (vfs.read.return
、vfs.read.return
など) でのみ使用できます。
例4.10 例4.9「disktop.stp」 出力サンプル
[...] Mon Sep 29 03:38:28 2008 , Average: 19Kb/sec, Read: 7Kb, Write: 89Kb UID PID PPID CMD DEVICE T BYTES 0 26319 26294 firefox sda5 W 90229 0 2758 2757 pam_timestamp_c sda5 R 8064 0 2885 1 cupsd sda5 W 1678 Mon Sep 29 03:38:38 2008 , Average: 1Kb/sec, Read: 7Kb, Write: 1Kb UID PID PPID CMD DEVICE T BYTES 0 2758 2757 pam_timestamp_c sda5 R 8064 0 2885 1 cupsd sda5 W 1678
4.2.2. ファイル読み取り/書き込みの I/O 時間の追跡
例4.11 iotime.stp
global start global entry_io global fd_io global time_io function timestamp:long() { return gettimeofday_us() - start } function proc:string() { return sprintf("%d (%s)", pid(), execname()) } probe begin { start = gettimeofday_us() } global filenames global filehandles global fileread global filewrite probe syscall.open { filenames[pid()] = user_string($filename) } probe syscall.open.return { if ($return != -1) { filehandles[pid(), $return] = filenames[pid()] fileread[pid(), $return] = 0 filewrite[pid(), $return] = 0 } else { printf("%d %s access %s fail\n", timestamp(), proc(), filenames[pid()]) } delete filenames[pid()] } probe syscall.read { if ($count > 0) { fileread[pid(), $fd] += $count } t = gettimeofday_us(); p = pid() entry_io[p] = t fd_io[p] = $fd } probe syscall.read.return { t = gettimeofday_us(); p = pid() fd = fd_io[p] time_io[p,fd] <<< t - entry_io[p] } probe syscall.write { if ($count > 0) { filewrite[pid(), $fd] += $count } t = gettimeofday_us(); p = pid() entry_io[p] = t fd_io[p] = $fd } probe syscall.write.return { t = gettimeofday_us(); p = pid() fd = fd_io[p] time_io[p,fd] <<< t - entry_io[p] } probe syscall.close { if (filehandles[pid(), $fd] != "") { printf("%d %s access %s read: %d write: %d\n", timestamp(), proc(), filehandles[pid(), $fd], fileread[pid(), $fd], filewrite[pid(), $fd]) if (@count(time_io[pid(), $fd])) printf("%d %s iotime %s time: %d\n", timestamp(), proc(), filehandles[pid(), $fd], @sum(time_io[pid(), $fd])) } delete fileread[pid(), $fd] delete filewrite[pid(), $fd] delete filehandles[pid(), $fd] delete fd_io[pid()] delete entry_io[pid()] delete time_io[pid(),$fd] }
例4.12 例4.11「iotime.stp」 出力サンプル
[...] 825946 3364 (NetworkManager) access /sys/class/net/eth0/carrier read: 8190 write: 0 825955 3364 (NetworkManager) iotime /sys/class/net/eth0/carrier time: 9 [...] 117061 2460 (pcscd) access /dev/bus/usb/003/001 read: 43 write: 0 117065 2460 (pcscd) iotime /dev/bus/usb/003/001 time: 7 [...] 3973737 2886 (sendmail) access /proc/loadavg read: 4096 write: 0 3973744 2886 (sendmail) iotime /proc/loadavg time: 11 [...]
- タイムスタンプ (マイクロ秒単位)
- プロセス ID およびプロセス名
access
またはiotime
のフラグ- アクセスされたファイル
access
と iotime
の行のペアが一緒に表示されます。access
行のタイムスタンプは、そのプロセスがファイルにアクセスを開始した時間を指します。その行の最後には、読み取り/書き込みされたデータ量がバイト単位で表示されます。iotime
の行では、読み取り/書き込みにプロセスが費やした時間がマイクロ秒単位で表示されます。
access
行の後に iotime
行が続いていない場合は、プロセスがデータの読み取りまたは書き込みを行わなかったことを意味します。
4.2.3. 累積 I/O の追跡
例4.13 traceio.stp
#! /usr/bin/env stap # traceio.stp # Copyright (C) 2007 Red Hat, Inc., Eugene Teo <eteo@redhat.com> # Copyright (C) 2009 Kai Meyer <kai@unixlords.com> # Fixed a bug that allows this to run longer # And added the humanreadable function # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as # published by the Free Software Foundation. # global reads, writes, total_io probe vfs.read.return { reads[pid(),execname()] += $return total_io[pid(),execname()] += $return } probe vfs.write.return { writes[pid(),execname()] += $return total_io[pid(),execname()] += $return } function humanreadable(bytes) { if (bytes > 1024*1024*1024) { return sprintf("%d GiB", bytes/1024/1024/1024) } else if (bytes > 1024*1024) { return sprintf("%d MiB", bytes/1024/1024) } else if (bytes > 1024) { return sprintf("%d KiB", bytes/1024) } else { return sprintf("%d B", bytes) } } probe timer.s(1) { foreach([p,e] in total_io- limit 10) printf("%8d %15s r: %12s w: %12s\n", p, e, humanreadable(reads[p,e]), humanreadable(writes[p,e])) printf("\n") # Note we don't zero out reads, writes and total_io, # so the values are cumulative since the script started. }
$return
も使用されていることに注意してください。
例4.14 例4.13「traceio.stp」 出力サンプル
[...] Xorg r: 583401 KiB w: 0 KiB floaters r: 96 KiB w: 7130 KiB multiload-apple r: 538 KiB w: 537 KiB sshd r: 71 KiB w: 72 KiB pam_timestamp_c r: 138 KiB w: 0 KiB staprun r: 51 KiB w: 51 KiB snmpd r: 46 KiB w: 0 KiB pcscd r: 28 KiB w: 0 KiB irqbalance r: 27 KiB w: 4 KiB cupsd r: 4 KiB w: 18 KiB Xorg r: 588140 KiB w: 0 KiB floaters r: 97 KiB w: 7143 KiB multiload-apple r: 543 KiB w: 542 KiB sshd r: 72 KiB w: 72 KiB pam_timestamp_c r: 138 KiB w: 0 KiB staprun r: 51 KiB w: 51 KiB snmpd r: 46 KiB w: 0 KiB pcscd r: 28 KiB w: 0 KiB irqbalance r: 27 KiB w: 4 KiB cupsd r: 4 KiB w: 18 KiB
4.2.4. I/O 監視 (デバイスごと)
例4.15 traceio2.stp
#! /usr/bin/env stap global device_of_interest probe begin { /* The following is not the most efficient way to do this. One could directly put the result of usrdev2kerndev() into device_of_interest. However, want to test out the other device functions */ dev = usrdev2kerndev($1) device_of_interest = MKDEV(MAJOR(dev), MINOR(dev)) } probe vfs.write, vfs.read { if (dev == device_of_interest) printf ("%s(%d) %s 0x%x\n", execname(), pid(), probefunc(), dev) }
usrdev2kerndev()
関数は、全体デバイス番号をカーネルが理解する書式に変換します。usrdev2kerndev()
が生成した出力は、特定デバイスのメジャー番号とマイナー番号を決定するために MKDEV()
、MINOR()
、および MAJOR()
関数とともに使用されます。
vfs_read
または vfs_write
)、およびカーネルデバイス番号が含まれます。
0x805
は /home
のデバイス番号全体です。/home
は、監視したいデバイスである /dev/sda5
にあります。
例4.16 例4.15「traceio2.stp」 出力サンプル
[...] synergyc(3722) vfs_read 0x800005 synergyc(3722) vfs_read 0x800005 cupsd(2889) vfs_write 0x800005 cupsd(2889) vfs_write 0x800005 cupsd(2889) vfs_write 0x800005 [...]
4.2.5. ファイルの読み取りおよび書き込みの監視
例4.17 inodewatch.stp
#! /usr/bin/env stap probe vfs.write, vfs.read { # dev and ino are defined by vfs.write and vfs.read if (dev == MKDEV($1,$2) # major/minor device && ino == $3) printf ("%s(%d) %s 0x%x/%u\n", execname(), pid(), probefunc(), dev, ino) }
- ファイルのメジャーデバイス番号
- ファイルのマイナーデバイス番号
- ファイルの
inode
番号
/etc/crontab
ファイルを監視する場合は、最初に stat -c '%D %i' /etc/crontab を実行します。これにより、次の出力が出力されます。
805 1078319
805
は、ベース 16 (16 進数) のデバイス番号です。最後の 2 桁がマイナーデバイス番号で、その上の数字がメジャー番号です。1078319
は inode
番号です。/etc/crontab
の監視を開始するには、stap inodewatch.stp 0x8 0x05 1078319 を実行します (0x
接頭辞は base-16 値を示します)。
vfs_read
または vfs_write
)、デバイス番号 (16 進形式)、および inode
番号が含まれます。例4.18「例4.17「inodewatch.stp」 出力サンプル」 には、stap inodewatch.stp 0x8 0x05 1078319 の出力が含まれます (スクリプトの実行中に cat /etc/crontab が実行された場合)。
例4.18 例4.17「inodewatch.stp」 出力サンプル
cat(16437) vfs_read 0x800005/1078319 cat(16437) vfs_read 0x800005/1078319
4.2.6. ファイル属性の変更の監視
例4.19 inodewatch2-simple.stp
global ATTR_MODE = 1 probe kernel.function("inode_setattr") { dev_nr = $inode->i_sb->s_dev inode_nr = $inode->i_ino if (dev_nr == ($1 << 20 | $2) # major/minor device && inode_nr == $3 && $attr->ia_valid & ATTR_MODE) printf ("%s(%d) %s 0x%x/%u %o %d\n", execname(), pid(), probefunc(), dev_nr, inode_nr, $attr->ia_mode, uid()) }
inode
番号を引数として取ります。この情報の取得方法は、「ファイルの読み取りおよび書き込みの監視」 を参照してください。
uid()
) が含まれている点で異なります。例4.20「例4.19「inodewatch2-simple.stp」 出力サンプル」 は 例4.19「inodewatch2-simple.stp」 の出力になります。/home/joe/bigfile
の監視中に、ユーザー joe
が chmod 777 /home/joe/bigfile と chmod 666 /home/joe/bigfile を実行しています。
例4.20 例4.19「inodewatch2-simple.stp」 出力サンプル
chmod(17448) inode_setattr 0x800005/6011835 100777 500 chmod(17449) inode_setattr 0x800005/6011835 100666 500
4.3. プロファイリング
4.3.1. 関数呼び出しのカウント
例4.21 functioncallcount.stp
#! /usr/bin/env stap # The following line command will probe all the functions # in kernel's memory management code: # # stap functioncallcount.stp "*@mm/*.c" probe kernel.function(@1).call { # probe functions listed on commandline called[probefunc()] <<< 1 # add a count efficiently } global called probe end { foreach (fn in called-) # Sort by call count (in decreasing order) # (fn+ in called) # Sort by function name printf("%s %d\n", fn, @count(called[fn])) exit() }
例4.22 例4.21「functioncallcount.stp」 出力サンプル
[...] __vma_link 97 __vma_link_file 66 __vma_link_list 97 __vma_link_rb 97 __xchg 103 add_page_to_active_list 102 add_page_to_inactive_list 19 add_to_page_cache 19 add_to_page_cache_lru 7 all_vm_events 6 alloc_pages_node 4630 alloc_slabmgmt 67 anon_vma_alloc 62 anon_vma_free 62 anon_vma_lock 66 anon_vma_prepare 98 anon_vma_unlink 97 anon_vma_unlock 66 arch_get_unmapped_area_topdown 94 arch_get_unmapped_exec_area 3 arch_unmap_area_topdown 97 atomic_add 2 atomic_add_negative 97 atomic_dec_and_test 5153 atomic_inc 470 atomic_inc_and_test 1 [...]
4.3.2. 呼び出し先の追跡
例4.23 para-callgraph.stp
#! /usr/bin/env stap function trace(entry_p, extra) { %( $# > 1 %? if (tid() in trace) %) printf("%s%s%s %s\n", thread_indent (entry_p), (entry_p>0?"->":"<-"), probefunc (), extra) } %( $# > 1 %? global trace probe $2.call { trace[tid()] = 1 } probe $2.return { delete trace[tid()] } %) probe $1.call { trace(1, $$parms) } probe $1.return { trace(-1, $$return) }
- その開始または終了が追跡対象となっている関数 ($1)。
- 2 つ目のオプションとなる trigger function (
$2
)。これは、スレッドごとの追跡を有効、無効にします。trigger function が終了していなければ、各スレッドにおける追跡は継続されます。
thread_indent()
を使用しているので、その出力には、$1
(追跡しているプローブ関数) のタイムスタンプ、プロセス名、およびスレッド ID が含まれます。thread_indent()
の詳細は、SystemTap 関数 のエントリーを参照してください。
例4.24 例4.23「para-callgraph.stp」 出力サンプル
[...] 267 gnome-terminal(2921): <-do_sync_read return=0xfffffffffffffff5 269 gnome-terminal(2921):<-vfs_read return=0xfffffffffffffff5 0 gnome-terminal(2921):->fput file=0xffff880111eebbc0 2 gnome-terminal(2921):<-fput 0 gnome-terminal(2921):->fget_light fd=0x3 fput_needed=0xffff88010544df54 3 gnome-terminal(2921):<-fget_light return=0xffff8801116ce980 0 gnome-terminal(2921):->vfs_read file=0xffff8801116ce980 buf=0xc86504 count=0x1000 pos=0xffff88010544df48 4 gnome-terminal(2921): ->rw_verify_area read_write=0x0 file=0xffff8801116ce980 ppos=0xffff88010544df48 count=0x1000 7 gnome-terminal(2921): <-rw_verify_area return=0x1000 12 gnome-terminal(2921): ->do_sync_read filp=0xffff8801116ce980 buf=0xc86504 len=0x1000 ppos=0xffff88010544df48 15 gnome-terminal(2921): <-do_sync_read return=0xfffffffffffffff5 18 gnome-terminal(2921):<-vfs_read return=0xfffffffffffffff5 0 gnome-terminal(2921):->fput file=0xffff8801116ce980
4.3.3. カーネルおよびユーザースペースで費やした時間の判定
例4.25 thread-times.stp
#! /usr/bin/env stap probe perf.sw.cpu_clock!, timer.profile { // NB: To avoid contention on SMP machines, no global scalars/arrays used, // only contention-free statistics aggregates. tid=tid(); e=execname() if (!user_mode()) kticks[e,tid] <<< 1 else uticks[e,tid] <<< 1 ticks <<< 1 tids[e,tid] <<< 1 } global uticks, kticks, ticks global tids probe timer.s(5), end { allticks = @count(ticks) printf ("%16s %5s %7s %7s (of %d ticks)\n", "comm", "tid", "%user", "%kernel", allticks) foreach ([e,tid] in tids- limit 20) { uscaled = @count(uticks[e,tid])*10000/allticks // SystemTap only performs integer arithmetic. // To avoid losing precision the decimal point is shifted // to the right four places (*100000). Think of this as // the original result value x.xxyy becoming xxxyy.0. // The integer percentage xxx is obtained // by dividing by 100 and the fractional percentage // is obtained with a modulo 100 operation. kscaled = @count(kticks[e,tid])*10000/allticks printf ("%16s %5d %3d.%02d%% %3d.%02d%%\n", e, tid, uscaled/100, uscaled%100, kscaled/100, kscaled%100) } printf("\n") delete uticks delete kticks delete ticks delete tids }
例4.26 例4.25「thread-times.stp」 出力サンプル
tid %user %kernel (of 20002 ticks) 0 0.00% 87.88% 32169 5.24% 0.03% 9815 3.33% 0.36% 9859 0.95% 0.00% 3611 0.56% 0.12% 9861 0.62% 0.01% 11106 0.37% 0.02% 32167 0.08% 0.08% 3897 0.01% 0.08% 3800 0.03% 0.00% 2886 0.02% 0.00% 3243 0.00% 0.01% 3862 0.01% 0.00% 3782 0.00% 0.00% 21767 0.00% 0.00% 2522 0.00% 0.00% 3883 0.00% 0.00% 3775 0.00% 0.00% 3943 0.00% 0.00% 3873 0.00% 0.00%
4.3.4. ポーリングアプリケーションの監視
例4.27 timeout.stp
#! /usr/bin/env stap # Copyright (C) 2009 Red Hat, Inc. # Written by Ulrich Drepper <drepper@redhat.com> # Modified by William Cohen <wcohen@redhat.com> global process, timeout_count, to global poll_timeout, epoll_timeout, select_timeout, itimer_timeout global nanosleep_timeout, futex_timeout, signal_timeout probe syscall.poll, syscall.epoll_wait { if (timeout) to[pid()]=timeout } probe syscall.poll.return { p = pid() if ($return == 0 && to[p] > 0 ) { poll_timeout[p]++ timeout_count[p]++ process[p] = execname() delete to[p] } } probe syscall.epoll_wait.return { p = pid() if ($return == 0 && to[p] > 0 ) { epoll_timeout[p]++ timeout_count[p]++ process[p] = execname() delete to[p] } } probe syscall.select.return { if ($return == 0) { p = pid() select_timeout[p]++ timeout_count[p]++ process[p] = execname() } } probe syscall.futex.return { if (errno_str($return) == "ETIMEDOUT") { p = pid() futex_timeout[p]++ timeout_count[p]++ process[p] = execname() } } probe syscall.nanosleep.return { if ($return == 0) { p = pid() nanosleep_timeout[p]++ timeout_count[p]++ process[p] = execname() } } probe kernel.function("it_real_fn") { p = pid() itimer_timeout[p]++ timeout_count[p]++ process[p] = execname() } probe syscall.rt_sigtimedwait.return { if (errno_str($return) == "EAGAIN") { p = pid() signal_timeout[p]++ timeout_count[p]++ process[p] = execname() } } probe syscall.exit { p = pid() if (p in process) { delete process[p] delete timeout_count[p] delete poll_timeout[p] delete epoll_timeout[p] delete select_timeout[p] delete itimer_timeout[p] delete futex_timeout[p] delete nanosleep_timeout[p] delete signal_timeout[p] } } probe timer.s(1) { ansi_clear_screen() printf (" pid | poll select epoll itimer futex nanosle signal| process\n") foreach (p in timeout_count- limit 20) { printf ("%5d |%7d %7d %7d %7d %7d %7d %7d| %-.38s\n", p, poll_timeout[p], select_timeout[p], epoll_timeout[p], itimer_timeout[p], futex_timeout[p], nanosleep_timeout[p], signal_timeout[p], process[p]) } }
poll
select
epoll
itimer
futex
nanosleep
signal
例4.28 例4.27「timeout.stp」 出力サンプル
uid | poll select epoll itimer futex nanosle signal| process 28937 | 148793 0 0 4727 37288 0 0| firefox 22945 | 0 56949 0 1 0 0 0| scim-bridge 0 | 0 0 0 36414 0 0 0| swapper 4275 | 23140 0 0 1 0 0 0| mixer_applet2 4191 | 0 14405 0 0 0 0 0| scim-launcher 22941 | 7908 1 0 62 0 0 0| gnome-terminal 4261 | 0 0 0 2 0 7622 0| escd 3695 | 0 0 0 0 0 7622 0| gdm-binary 3483 | 0 7206 0 0 0 0 0| dhcdbd 4189 | 6916 0 0 2 0 0 0| scim-panel-gtk 1863 | 5767 0 0 0 0 0 0| iscsid 2562 | 0 2881 0 1 0 1438 0| pcscd 4257 | 4255 0 0 1 0 0 0| gnome-power-man 4278 | 3876 0 0 60 0 0 0| multiload-apple 4083 | 0 1331 0 1728 0 0 0| Xorg 3921 | 1603 0 0 0 0 0 0| gam_server 4248 | 1591 0 0 0 0 0 0| nm-applet 3165 | 0 1441 0 0 0 0 0| xterm 29548 | 0 1440 0 0 0 0 0| httpd 1862 | 0 0 0 0 0 1438 0| iscsid
timer.s()
) を編集すると、サンプル時間を長くすることができます。例4.21「functioncallcount.stp」 の出力には、上位 20 位のポーリングアプリケーションの名前と UID、各アプリケーションがシステムコールのポーリングを行った回数が含まれています。例4.28「例4.27「timeout.stp」 出力サンプル」 はスクリプトの抜粋になります。
4.3.5. 最もよく使われるシステムコールの追跡
poll
select
epoll
itimer
futex
nanosleep
signal
例4.29 topsys.stp
#! /usr/bin/env stap # # This script continuously lists the top 20 systemcalls in the interval # 5 seconds # global syscalls_count probe syscall.* { syscalls_count[name]++ } function print_systop () { printf ("%25s %10s\n", "SYSCALL", "COUNT") foreach (syscall in syscalls_count- limit 20) { printf("%25s %10d\n", syscall, syscalls_count[syscall]) } delete syscalls_count } probe timer.s(5) { print_systop () printf("--------------------------------------------------------------\n") }
例4.30 例4.29「topsys.stp」 出力サンプル
-------------------------------------------------------------- SYSCALL COUNT gettimeofday 1857 read 1821 ioctl 1568 poll 1033 close 638 open 503 select 455 write 391 writev 335 futex 303 recvmsg 251 socket 137 clock_gettime 124 rt_sigprocmask 121 sendto 120 setitimer 106 stat 90 time 81 sigreturn 72 fstat 66 --------------------------------------------------------------
4.3.6. プロセスごとのシステムコールボリュームの追跡
例4.31 syscalls_by_proc.stp
#! /usr/bin/env stap # Copyright (C) 2006 IBM Corp. # # This file is part of systemtap, and is free software. You can # redistribute it and/or modify it under the terms of the GNU General # Public License (GPL); either version 2, or (at your option) any # later version. # # Print the system call count by process name in descending order. # global syscalls probe begin { print ("Collecting data... Type Ctrl-C to exit and display results\n") } probe syscall.* { syscalls[execname()]++ } probe end { printf ("%-10s %-s\n", "#SysCalls", "Process Name") foreach (proc in syscalls-) printf("%-10d %-s\n", syscalls[proc], proc) }
例4.32 例4.29「topsys.stp」 出力サンプル
Collecting data... Type Ctrl-C to exit and display results #SysCalls Process Name 1577 multiload-apple 692 synergyc 408 pcscd 376 mixer_applet2 299 gnome-terminal 293 Xorg 206 scim-panel-gtk 95 gnome-power-man 90 artsd 85 dhcdbd 84 scim-bridge 78 gnome-screensav 66 scim-launcher [...]
例4.33 syscalls_by_pid.stp
#! /usr/bin/env stap # Copyright (C) 2006 IBM Corp. # # This file is part of systemtap, and is free software. You can # redistribute it and/or modify it under the terms of the GNU General # Public License (GPL); either version 2, or (at your option) any # later version. # # Print the system call count by process ID in descending order. # global syscalls probe begin { print ("Collecting data... Type Ctrl-C to exit and display results\n") } probe syscall.* { syscalls[pid()]++ } probe end { printf ("%-10s %-s\n", "#SysCalls", "PID") foreach (pid in syscalls-) printf("%-10d %-d\n", syscalls[pid], pid) }
probe timer.s(5) { exit() }
4.4. 競合ユーザースペースのロックの特定
futex
競合が原因と疑われるハングの調査に役立ちます。
futex
競合が発生します。場合によっては、これは競合しているプロセス間のデッドロックになり、アプリケーションがハングしているように見えます。
futex
システムコールをプローブします。
例4.34 futexes.stp
#! /usr/bin/env stap # This script tries to identify contended user-space locks by hooking # into the futex system call. global thread_thislock # short global thread_blocktime # global FUTEX_WAIT = 0 /*, FUTEX_WAKE = 1 */ global lock_waits # long-lived stats on (tid,lock) blockage elapsed time global process_names # long-lived pid-to-execname mapping probe syscall.futex { if (op != FUTEX_WAIT) next # don't care about WAKE event originator t = tid () process_names[pid()] = execname() thread_thislock[t] = $uaddr thread_blocktime[t] = gettimeofday_us() } probe syscall.futex.return { t = tid() ts = thread_blocktime[t] if (ts) { elapsed = gettimeofday_us() - ts lock_waits[pid(), thread_thislock[t]] <<< elapsed delete thread_blocktime[t] delete thread_thislock[t] } } probe end { foreach ([pid+, lock] in lock_waits) printf ("%s[%d] lock %p contended %d times, %d avg us\n", process_names[pid], pid, lock, @count(lock_waits[pid,lock]), @avg(lock_waits[pid,lock])) }
- 競合の原因となったプロセスの名前と ID
- 競合対象となったメモリー領域
- メモリー領域が競合された回数
- プローブ中の競合の平均時間
例4.35 例4.34「futexes.stp」 出力サンプル
[...] automount[2825] lock 0x00bc7784 contended 18 times, 999931 avg us synergyc[3686] lock 0x0861e96c contended 192 times, 101991 avg us synergyc[3758] lock 0x08d98744 contended 192 times, 101990 avg us synergyc[3938] lock 0x0982a8b4 contended 192 times, 101997 avg us [...]
第5章 SystemTap のエラーを理解する
[man warning::example1] [man error::example2]
5.1. 解析エラーとセマンティックエラー
parse error: expected abc, saw xyz
スクリプトに文法的なエラーまたは誤字や脱字のエラーが含まれています。プローブのコンテキストから考えると、SystemTap は間違ったコンストラクトのタイプを検出しました。
probe vfs.read probe vfs.write
parse error: expected one of '. , ( ? ! { = +=' saw: keyword at perror.stp:2:1 1 parse error(s).
parse error: embedded code in unprivileged script
スクリプトには危険な埋め込み C コードが含まれています (%{
%}
で囲まれたコードブロック)。SystemTap では、スクリプトに C コードを埋め込むことができるため、目的にあった tapsets がない場合には便利です。ただし、埋め込みの C コンストラクトは安全ではありません。そのため、スクリプトにこのような構造を検出すると SystemTap はこのエラーで警告を発します。
stapdev
グループのメンバーである (または root 特権がある) 場合には、オプション -g を使用して guru モードでスクリプトを実行します。
stap -g script
semantic error: type mismatch for identifier 'ident' ... string vs. long
スクリプト内の ident
関数は、間違ったタイプ (%s
または %d
) を使用していました。このエラーは 例5.1「error-variable.stp」 に表示されます。関数 execname()
が文字列を返すため、書式指定子は %d
ではなく %s
にしてください。
例5.1 error-variable.stp
probe syscall.open { printf ("%d(%d) open\n", execname(), pid()) }
semantic error: unresolved type for identifier 'ident'
識別子 (変数など) が使用されているがタイプ (整数または文字列) を特定できません。たとえば、printf ステートメントに変数を使用しているのに、スクリプトでは変数に値を割り当てていない場合などにこのエラーが発生します。
semantic error: Expecting symbol or array index expression
SystemTap ではアレイ内の場所や変数に値を割り当てることはできません。割り当ての目的地が有効な目的地になっていません。以下のようなサンプルコードを使用すると、このエラーが発生することになります。
probe begin { printf("x") = 1 }
semantic error: unresolved function call (変数 N 関数の検索中に発生するエラー)
スクリプト内の関数呼び出しまたはアレイインデックス式が無効な数の引数/パラメーターを使用しました。SystemTap では、arity (アリティー) はアレイのインデックス数または関数へのパラメーター数を参照することができます。
semantic error: array locals not supported, missing global declaration?
アレイをグローバル変数と宣言せずに、スクリプトがアレイ演算を使用しました (グローバル変数は、SystemTap スクリプトでの使用後に宣言されることができます)。アレイが一貫性のないアリティーと使用されると、同様のメッセージが表示されます。
semantic error: variable ’vaar’ modified during ’foreach’ iteration
アレイ var
がアクティブな foreach ループ内で修正 (割り当てまたは削除) されています。このエラーは、スクリプト内の演算が foreach ループ内で関数呼び出しを実行しても表示されます。
semantic error: probe point mismatch at position N, while resolving probe point pnt
SystemTap は、イベントまたは SystemTap 関数 pnt
が参照しているものを理解できませんでした。これは通常、SystemTap が tapset ライブラリー内で pnt
に一致するものを見つけられなかったことを意味します。ここでの N は、エラーの行とコラムを指します。
semantic error: no match for probe point, while resolving probe point pnt
イベント/ハンドラー関数 pnt
は、さまざまな理由で解決できませんでした。このエラーは、スクリプトにイベント kernel.function("name")
が含まれ、name が存在しない場合に発生します。このエラーはスクリプトに無効なカーネルファイル名やソース行数が含まれていることを意味する場合もあります。
semantic error: unresolved target-symbol expression
スクリプトのハンドラーはターゲット変数を参照しますが、変数の値が解決できませんでした。このエラーは、ハンドラーがターゲット変数を参照した際にその変数がコンテキスト内で無効であることも意味します。これは、生成されたコードのコンパイラー最適化の結果である可能性もあります。
semantic error: libdwfl failure
デバッグ情報の処理に問題がありました。ほとんどの場合、このエラーは kernel-debuginfo パッケージのインストールが原因で発生します。インストールされた kernel-debuginfo パッケージ自体に、一貫性または正確性の問題がある可能性があります。
semantic error: cannot find package debuginfo
SystemTap は適切な kernel-debuginfo を見つけることができませんでした。
5.2. ランタイムエラーおよび警告
WARNING: Number of errors: N, skipped probes: M
この実行中に、エラー、プローブの省略、またはその両方が発生しました。N と M は、発生したエラーの数と、特定の時間間隔でイベントハンドラーを実行するのに時間がかかりすぎるなどの条件によりスキップされたプローブの数です。
第6章 リファレンス
- SystemTap Wiki
- 『SystemTap Wiki』 とは、SystemTap のデプロイメント、使用、および開発に関連するリンクや記事がまとめられているページです。 http://sourceware.org/systemtap/wiki/HomePage をご覧ください。
- SystemTap チュートリアル
- 本ガイドのコンテンツの多くは 『SystemTap Tutorial』 を元にしています。『SystemTap Tutorial』 は、C++ やカーネル開発などに関して中から高程度の知識を有するユーザー向けの内容になります。http://sourceware.org/systemtap/tutorial/ をご覧ください。
- man stapprobes
- man ページの
stapprobes
では、SystemTap で対応している各種のプローブポイントおよび SystemTap tapset ライブラリーで定義している他のエイリアスを紹介しています。man ページの下部には、stapprobes.scsi
、stapprobes.kprocess
、stapprobes.signal
など、特定のシステムコンポーネントの同様のプローブポイントを列挙する他の man ページのリストが含まれています。 - man stapfuncs
- man ページの
stapfuncs
は、SystemTap tapset ライブラリーで対応している多数の関数および各関数に規定の構文を説明しています。ただし、対応している関数が すべて 記載されているわけではない点に注意してください。説明がない関数が他にもあります。 - SystemTap Language Reference (SystemTap 言語リファレンス)
- 本ガイドは、SystemTap の言語設定および構文がすべて記載されているリファレンスです。C++ および他の似たようなプログラミング言語の基本的な知識または中程度の知識をお持ちのユーザーを対象としています。『SystemTap Language Reference』 は、すべてのユーザーを対象に http://sourceware.org/systemtap/langref/ で公開されています。
- Tapset Developers Guide
- SystemTap スクリプトの記述に熟達したら、独自のタップセットの記述に挑戦することができます。『Tapset Developers Guide』 では、タップセットライブラリーに関数を追加する方法を説明しています。
- Test Suite
systemtap-testsuite
パッケージを使用すると、ソースからビルドしなくても SystemTap ツールチェーン全体をテストできます。また、研究や検証対象となる SystemTap スクリプトのサンプルも数多く収納されています。一部のサンプルスクリプトは、4章便利な SystemTap スクリプト で説明しています。デフォルトでは、systemtap-testsuite
に含まれるサンプルスクリプトは/usr/share/systemtap/testsuite/systemtap.examples
にあります。
付録A 更新履歴
改訂履歴 | |||
---|---|---|---|
改訂 7-7 | Mon Aug 5 2019 | ||
| |||
改訂 7-6 | Tue Oct 30 2018 | ||
| |||
改訂 7-5.1 | Mon Jun 18 2018 | ||
| |||
改訂 7-5 | Tue Jan 09 2018 | ||
| |||
改訂 7-4 | Wed Jul 26 2017 | ||
| |||
改訂 7-3.9 | Tue May 16 2017 | ||
| |||
改訂 1-8 | Wed Oct 19 2016 | ||
| |||
改訂 1-6 | Wed Jan 20 2016 | ||
| |||
改訂 1-5 | Thu Nov 11 2015 | ||
| |||
改訂 0-3 | Fri Dec 6 2013 | ||
|
索引
シンボル
- $count
- サンプル使用例
- ローカル変数, ファイル読み取り/書き込みの I/O 時間の追跡
- $return
- サンプル使用例
- ローカル変数, ディスク読み取り/書き込みトラフィックの要約, 累積 I/O の追跡
- 'foreach' 中に変数が修正される
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
- @avg (整数抽出)
- 統計集計の計算
- アレイ演算, 統計集計の計算
- @count (整数抽出)
- 統計集計の計算
- アレイ演算, 統計集計の計算
- @max (整数抽出)
- 統計集計の計算
- アレイ演算, 統計集計の計算
- @min (整数抽出)
- 統計集計の計算
- アレイ演算, 統計集計の計算
- @sum (整数抽出)
- 統計集計の計算
- アレイ演算, 統計集計の計算
- はじめに
- SystemTap の機能, SystemTap の機能
- パフォーマンスの監視, はじめに
- 本ガイドの目的, 本ガイドの目的
- 目的、ドキュメント, 本ガイドの目的
- アグリゲーションのオーバーフロー
- ランタイムエラー/警告
- SystemTap のエラーを理解する, ランタイムエラーおよび警告
- アレイ, 連想アレイ
- (参照 連想アレイ)
- アレイ/アレイ要素の消去
- アレイ演算, アレイおよびアレイ要素の消去/削除
- Delete 演算子, アレイおよびアレイ要素の消去/削除
- 仮想ファイルシステムの読み込み (累積的以外)、集計, アレイおよびアレイ要素の消去/削除
- 同一プローブ内の複数のアレイ演算, アレイおよびアレイ要素の消去/削除
- アレイからの値の読み取り
- アレイ演算, アレイからの値の読み取り
- シンプルな計算でのアレイの使用, アレイからの値の読み取り
- 空の一意のキー, アレイからの値の読み取り
- タイムスタンプ差分の計算
- アレイ演算, アレイからの値の読み取り
- アレイを使った代数公式
- アレイからの値の読み取り
- アレイ演算, アレイからの値の読み取り
- アレイメンバーシップのテスト
- 条件付きステートメント、アレイの使用
- アレイ演算, 条件付きステートメントにおけるアレイの使用
- アレイローカルがサポートされない
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
- アレイ内での複数要素の処理
- foreach
- アレイ演算, アレイ内での複数要素の処理
- foreach 出力の制限
- アレイ演算, アレイ内での複数要素の処理
- foreach 出力の順序
- アレイ演算, アレイ内での複数要素の処理
- アレイ演算, アレイ内での複数要素の処理
- 累積的仮想ファイルシステムの読み込み、集計
- アレイ演算, アレイ内での複数要素の処理
- アレイ内の複数要素
- アレイ演算, アレイ内での複数要素の処理
- アレイ演算
- アレイ/アレイ要素の消去, アレイおよびアレイ要素の消去/削除
- Delete 演算子, アレイおよびアレイ要素の消去/削除
- 仮想ファイルシステムの読み込み (累積的以外)、集計, アレイおよびアレイ要素の消去/削除
- 同一プローブ内の複数のアレイ演算, アレイおよびアレイ要素の消去/削除
- アレイおよびアレイ要素の削除, アレイおよびアレイ要素の消去/削除
- アレイからの値の読み取り, アレイからの値の読み取り
- シンプルな計算でのアレイの使用, アレイからの値の読み取り
- タイムスタンプ差分の計算, アレイからの値の読み取り
- 空の一意のキー, アレイからの値の読み取り
- アレイ内での複数要素の処理, アレイ内での複数要素の処理
- foreach, アレイ内での複数要素の処理
- foreach 出力の制限, アレイ内での複数要素の処理
- foreach 出力の順序, アレイ内での複数要素の処理
- 反復、アレイ内の要素の処理, アレイ内での複数要素の処理
- 累積的仮想ファイルシステムの読み込み、集計, アレイ内での複数要素の処理
- アレイ内の複数要素, アレイ内での複数要素の処理
- 条件付きステートメント、アレイの使用, 条件付きステートメントにおけるアレイの使用
- アレイメンバーシップのテスト, 条件付きステートメントにおけるアレイの使用
- 統計集計の計算, 統計集計の計算
- 連想アレイ, SystemTap でのアレイ演算
- 関連する値の割り当て, 関連する値の割り当て
- タイムスタンプをプロセス名に関連付ける, 関連する値の割り当て
- 関連する値の増加, 関連する値の増加
- 仮想ファイルシステムの読み込みの集計 (VFS 読み込み), 関連する値の増加
- アーキテクチャー表記法、決定, 必要なカーネル情報パッケージのインストール
- アーキテクチャー表記法の決定, 必要なカーネル情報パッケージのインストール
- イベント
- イベントおよびハンドラー, SystemTap の作動方法
- イベントタイプ
- SystemTap の作動方法, SystemTap の作動方法
- イベントワイルドカード, イベント
- イベント内のワイルドカード, イベント
- インストルメンテーションモジュール
- クロスインストルメンテーション, 他のコンピューター用のインストルメンテーション生成
- インストール
- systemtap パッケージ, SystemTap のインストール
- systemtap-runtime パッケージ, SystemTap のインストール
- カーネルバージョン、判断, 必要なカーネル情報パッケージのインストール
- カーネル情報パッケージ, 必要なカーネル情報パッケージのインストール
- 初期テスト, 初期テスト
- 必要なパッケージ, 必要なカーネル情報パッケージのインストール
- 設定とインストール, インストールと設定
- インデックス式
- 概要
- アレイ, 連想アレイ
- エラー
- ランタイムエラー/警告, ランタイムエラーおよび警告
- aggregate element not found, ランタイムエラーおよび警告
- aggregation overflow, ランタイムエラーおよび警告
- division by 0, ランタイムエラーおよび警告
- MAXACTION exceeded, ランタイムエラーおよび警告
- MAXNESTING exceeded, ランタイムエラーおよび警告
- number of errors: N, skipped probes: M, ランタイムエラーおよび警告
- pointer dereference fault, ランタイムエラーおよび警告
- コピー障害, ランタイムエラーおよび警告
- 解析エラー/セマンティックエラー, 解析エラーとセマンティックエラー
- 'foreach' 中に変数が修正される, 解析エラーとセマンティックエラー
- guru モード, 解析エラーとセマンティックエラー
- libdwfl 失敗, 解析エラーとセマンティックエラー
- スクリプトの文法的なエラー/誤字のエラー, 解析エラーとセマンティックエラー
- プローブの不一致, 解析エラーとセマンティックエラー
- プローブポイントに一致するものがない, 解析エラーとセマンティックエラー
- 変数/アレイに無効な値, 解析エラーとセマンティックエラー
- 特権のないスクリプトにコードが埋め込まれている, 解析エラーとセマンティックエラー
- 解決できないターゲット記号式, 解析エラーとセマンティックエラー
- 解決できない識別子のタイプ, 解析エラーとセマンティックエラー
- 解決できない関数呼び出し, 解析エラーとセマンティックエラー
- 記号やアレイに期待されているインデックス式, 解析エラーとセマンティックエラー
- 識別子タイプの不一致, 解析エラーとセマンティックエラー
- 非グローバルアレイ, 解析エラーとセマンティックエラー
- オプション、stap
- カーネル/ユーザースペースで費やした時間、判定
- SystemTap スクリプトの例, カーネルおよびユーザースペースで費やした時間の判定
- カーネルおよびユーザースペース、費やした時間の判定
- SystemTap スクリプトの例, カーネルおよびユーザースペースで費やした時間の判定
- カーネルおよびユーザースペースで費やした時間の判定
- SystemTap スクリプトの例, カーネルおよびユーザースペースで費やした時間の判定
- カーネルバージョン、判断, 必要なカーネル情報パッケージのインストール
- カーネルバージョンの判断, 必要なカーネル情報パッケージのインストール
- カーネル情報パッケージ, 必要なカーネル情報パッケージのインストール
- キーのペア
- 概要
- アレイ, 連想アレイ
- クロスインストルメンテーション
- SystemTap スクリプトからインストルメンテーションを生成する, 他のコンピューター用のインストルメンテーション生成
- SystemTap スクリプトからカーネルモジュールを構築する, 他のコンピューター用のインストルメンテーション生成
- インストルメンテーションモジュール, 他のコンピューター用のインストルメンテーション生成
- ターゲットカーネル, 他のコンピューター用のインストルメンテーション生成
- ターゲットシステム, 他のコンピューター用のインストルメンテーション生成
- ホストシステム, 他のコンピューター用のインストルメンテーション生成
- 利点:, 他のコンピューター用のインストルメンテーション生成
- 設定
- ホストシステムおよびターゲットシステム, 他のコンピューター用のインストルメンテーション生成
- クロスインストルメンテーションの利点, 他のコンピューター用のインストルメンテーション生成
- コピー障害
- ランタイムエラー/警告
- SystemTap のエラーを理解する, ランタイムエラーおよび警告
- コマンドラインの引数
- SystemTap ハンドラーコンストラクト
- ハンドラー, コマンドラインの引数
- コンポーネント
- SystemTap スクリプト
- 概要, SystemTap スクリプト
- システムコール、監視
- SystemTap スクリプトの例, 最もよく使われるシステムコールの追跡
- システムコールの監視
- SystemTap スクリプトの例, 最もよく使われるシステムコールの追跡
- システムコールの監視 (プロセスごとのボリューム)
- SystemTap スクリプトの例, プロセスごとのシステムコールボリュームの追跡
- システムコールボリューム (プロセスごと)、監視
- SystemTap スクリプトの例, プロセスごとのシステムコールボリュームの追跡
- シンプルな計算でのアレイの使用
- アレイからの値の読み取り
- アレイ演算, アレイからの値の読み取り
- スクリプト
- 概要, SystemTap スクリプト
- イベントおよびハンドラー, SystemTap スクリプト
- コンポーネント, SystemTap スクリプト
- 形式および構文, SystemTap スクリプト
- 関数, SystemTap スクリプト
- スクリプトの例
- CPU ティック, カーネルおよびユーザースペースで費やした時間の判定
- ctime()、使用例, ディスク読み取り/書き込みトラフィックの要約
- futex システムコール, 競合ユーザースペースのロックの特定
- I/O 時間の監視, ファイル読み取り/書き込みの I/O 時間の追跡
- if/else 条件、代替の構文, ネットワークのプロファイリング
- inode 番号, ファイルの読み取りおよび書き込みの監視
- net/socket.c、関数の追跡, ネットワークソケットコードで呼び出された関数の追跡
- stat -c、ファイルデバイス番号の決定 (整数形式), ファイルの読み取りおよび書き込みの監視
- stat -c、全体デバイス番号の決定, I/O 監視 (デバイスごと)
- thread_indent()、サンプル使用例, 呼び出し先の追跡
- timer.ms()、サンプル使用例, 関数呼び出しのカウント
- timer.s()、サンプル使用例, ポーリングアプリケーションの監視, 最もよく使われるシステムコールの追跡
- trigger function, 呼び出し先の追跡
- usrdev2kerndev(), I/O 監視 (デバイスごと)
- カーネルおよびユーザースペースで費やした時間の判定, カーネルおよびユーザースペースで費やした時間の判定
- システムコールの監視, 最もよく使われるシステムコールの追跡
- システムコールの監視 (プロセスごとのボリューム), プロセスごとのシステムコールボリュームの追跡
- ディスク I/O トラフィックの要約, ディスク読み取り/書き込みトラフィックの要約
- デバイス I/O の監視, I/O 監視 (デバイスごと)
- ネットワークのプロファイリング, ネットワークのプロファイリング, カーネルでのネットワークパケットドロップの監視
- ネットワークソケットコードで呼び出された関数の追跡, ネットワークソケットコードで呼び出された関数の追跡
- ファイルの読み取りおよび書き込みの監視, ファイルの読み取りおよび書き込みの監視
- ファイルデバイス番号 (整数形式), ファイルの読み取りおよび書き込みの監視
- ファイル属性の変更の監視, ファイル属性の変更の監視
- プロセスのデッドロック (futex 競合により発生), 競合ユーザースペースのロックの特定
- ポーリングアプリケーションの監視, ポーリングアプリケーションの監視
- 全体デバイス番号 (コマンドライン引数として使用), I/O 監視 (デバイスごと)
- 呼び出し先の追跡, 呼び出し先の追跡
- 着信 TCP 接続の監視, 着信 TCP 接続の監視
- 競合ユーザースペースのロック (futex 競合) の特定, 競合ユーザースペースのロックの特定
- 累積 I/O の追跡, 累積 I/O の追跡
- 複数のコマンドライン引数、例, 呼び出し先の追跡
- 関数呼び出しの集計, 関数呼び出しのカウント
- スクリプトの文法的なエラー/誤字のエラー
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
- スクリプトの誤字のエラー
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
- ステートメントブロック
- SystemTap スクリプト
- 概要, SystemTap スクリプト
- セッション、SystemTap, アーキテクチャー
- タイムスタンプ、プロセス名との関連付け
- 関連する値の割り当て
- アレイ演算, 関連する値の割り当て
- タイムスタンプをプロセス名に関連付ける
- 関連する値の割り当て
- アレイ演算, 関連する値の割り当て
- タイムスタンプ差分、計算
- アレイからの値の読み取り
- アレイ演算, アレイからの値の読み取り
- タイムスタンプ差分の計算
- アレイからの値の読み取り
- アレイ演算, アレイからの値の読み取り
- ターゲットカーネル
- クロスインストルメンテーション, 他のコンピューター用のインストルメンテーション生成
- ターゲットシステム
- クロスインストルメンテーション, 他のコンピューター用のインストルメンテーション生成
- ターゲットシステムおよびホストシステム
- configuration, 他のコンピューター用のインストルメンテーション生成
- ターゲット記号式、解決できない
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
- テスト、初期, 初期テスト
- ディスク I/O トラフィック、要約
- スクリプトの例, ディスク読み取り/書き込みトラフィックの要約
- ディスク I/O トラフィックの要約
- スクリプトの例, ディスク読み取り/書き込みトラフィックの要約
- デバイス I/O の監視
- SystemTap スクリプトの例, I/O 監視 (デバイスごと)
- デバイス I/O、監視
- SystemTap スクリプトの例, I/O 監視 (デバイスごと)
- ネットワークのプロファイリング
- SystemTap スクリプトの例, ネットワークのプロファイリング, カーネルでのネットワークパケットドロップの監視
- ネットワークソケットコード、呼び出された関数の追跡
- SystemTap スクリプトの例, ネットワークソケットコードで呼び出された関数の追跡
- ネットワークソケットコードで呼び出された関数、追跡
- SystemTap スクリプトの例, ネットワークソケットコードで呼び出された関数の追跡
- ネットワークソケットコードで呼び出された関数の追跡
- SystemTap スクリプトの例, ネットワークソケットコードで呼び出された関数の追跡
- ネットワークトラフィック、監視
- SystemTap スクリプトの例, ネットワークのプロファイリング, カーネルでのネットワークパケットドロップの監視
- ハンドラー
- SystemTap ハンドラーコンストラクト, 基本的な SystemTap ハンドラーコンストラクト
- コマンドラインの引数, コマンドラインの引数
- 変数, 変数
- 構文および形式, 基本的な SystemTap ハンドラーコンストラクト
- 条件付き (conditional) ステートメント, 条件付き (conditional) ステートメント
- For ループ, 条件付き (conditional) ステートメント
- if/else, 条件付き (conditional) ステートメント
- While ループ, 条件付き (conditional) ステートメント
- 条件演算子, 条件付き (conditional) ステートメント
- 概要, Systemtap ハンドラー/ボディー
- ハンドラーおよびイベント, SystemTap の作動方法
- SystemTap スクリプト
- 概要, SystemTap スクリプト
- ハンドラー関数, Systemtap ハンドラー/ボディー
- パフォーマンスの監視
- はじめに, はじめに
- ファイルのデバイス番号 (整数形式)
- SystemTap スクリプトの例, ファイルの読み取りおよび書き込みの監視
- ファイルの読み取り/書き込み、監視
- SystemTap スクリプトの例, ファイルの読み取りおよび書き込みの監視
- ファイルの読み取りおよび書き込みの監視
- SystemTap スクリプトの例, ファイルの読み取りおよび書き込みの監視
- ファイルへの書き込み/読み取り、監視
- SystemTap スクリプトの例, ファイルの読み取りおよび書き込みの監視
- ファイルデバイス番号 (整数形式)
- SystemTap スクリプトの例, ファイルの読み取りおよび書き込みの監視
- ファイル属性、変更の監視
- SystemTap スクリプトの例, ファイル属性の変更の監視
- ファイル属性の変更、監視
- SystemTap スクリプトの例, ファイル属性の変更の監視
- ファイル属性の変更の監視
- SystemTap スクリプトの例, ファイル属性の変更の監視
- フライトレコーダーモード, SystemTap フライトレコーダーモード
- ファイルモード, ファイルフライトレコーダー
- メモリー内モード, メモリー内フライトレコーダー
- プロセスのデッドロック (futex 競合により発生)
- SystemTap スクリプトの例, 競合ユーザースペースのロックの特定
- プローブ
- SystemTap スクリプト
- 概要, SystemTap スクリプト
- プローブの不一致
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
- プローブポイント (一致なし)
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
- プローブポイントに一致するものがない
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
- ホストシステム
- クロスインストルメンテーション, 他のコンピューター用のインストルメンテーション生成
- ホストシステムおよびターゲットシステム
- クロスインストルメンテーション
- ポーリングアプリケーション、監視
- SystemTap スクリプトの例, ポーリングアプリケーションの監視
- ポーリングアプリケーションの監視
- SystemTap スクリプトの例, ポーリングアプリケーションの監視
- メンバーシップ (アレイ内)、テスト
- 条件付きステートメント、アレイの使用
- アレイ演算, 条件付きステートメントにおけるアレイの使用
- ユーザーおよびカーネルスペース、費やした時間の判定
- SystemTap スクリプトの例, カーネルおよびユーザースペースで費やした時間の判定
- ランタイムエラー/警告
- SystemTap のエラーを理解する, ランタイムエラーおよび警告
- aggregate element not found, ランタイムエラーおよび警告
- aggregation overflow, ランタイムエラーおよび警告
- division by 0, ランタイムエラーおよび警告
- MAXACTION exceeded, ランタイムエラーおよび警告
- MAXNESTING exceeded, ランタイムエラーおよび警告
- number of errors: N, skipped probes: M, ランタイムエラーおよび警告
- pointer dereference fault, ランタイムエラーおよび警告
- コピー障害, ランタイムエラーおよび警告
- ローカル変数
- name, Systemtap ハンドラー/ボディー
- サンプル使用例
- $count, ファイル読み取り/書き込みの I/O 時間の追跡
- $return, ディスク読み取り/書き込みトラフィックの要約, 累積 I/O の追跡
- 一意のキー
- 概要
- アレイ, 連想アレイ
- 仮想ファイルシステム の読み込み (累積的)、集計
- アレイ内での複数要素の処理
- アレイ演算, アレイ内での複数要素の処理
- 仮想ファイルシステムの読み込み (累積的以外)、集計
- アレイ/アレイ要素の消去
- アレイ演算, アレイおよびアレイ要素の消去/削除
- 仮想ファイルシステムの読み込みの集計 (VFS 読み込み)
- 関連する値の増加
- アレイ演算, 関連する値の増加
- 使用方法
- SystemTap スクリプトの実行, SystemTap スクリプトの実行
- オプション、stap, SystemTap スクリプトの実行
- 便利な SystemTap スクリプトの例, 便利な SystemTap スクリプト
- 値、割り当て
- アレイ演算, 関連する値の割り当て
- 全体デバイス番号 (コマンドライン引数として使用)
- SystemTap スクリプトの例, I/O 監視 (デバイスごと)
- 初期テスト, 初期テスト
- 反復、アレイ内の要素の処理
- アレイ内での複数要素の処理
- アレイ演算, アレイ内での複数要素の処理
- 同一プローブ内の複数のアレイ演算
- アレイ/アレイ要素の消去
- アレイ演算, アレイおよびアレイ要素の消去/削除
- 同期および非同期イベントの例
- イベント, イベント
- 同期イベント
- イベント, イベント
- 呼び出し先の追跡
- SystemTap スクリプトの例, 呼び出し先の追跡
- 変数
- SystemTap ハンドラーコンストラクト
- ハンドラー, 変数
- 変数 (ローカル)
- name, Systemtap ハンドラー/ボディー
- サンプル使用例
- $count, ファイル読み取り/書き込みの I/O 時間の追跡
- $return, ディスク読み取り/書き込みトラフィックの要約, 累積 I/O の追跡
- 変数/アレイに無効な値
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
- 形式および構文
- printf(), Systemtap ハンドラー/ボディー
- SystemTap スクリプト
- 概要, SystemTap スクリプト
- SystemTap ハンドラーコンストラクト
- ハンドラー, 変数
- 必要なパッケージ, 必要なカーネル情報パッケージのインストール
- 整数抽出
- 統計集計の計算
- アレイ演算, 統計集計の計算
- 書式指定子
- printf(), Systemtap ハンドラー/ボディー
- 書式文字列
- printf(), Systemtap ハンドラー/ボディー
- 最も大きいディスクの読み取り/書き込み、識別
- スクリプトの例, ディスク読み取り/書き込みトラフィックの要約
- 最も大きいディスクの読み取り/書き込みの特定
- スクリプトの例, ディスク読み取り/書き込みトラフィックの要約
- 本ガイドの目的
- はじめに, 本ガイドの目的
- 条件付きステートメント、アレイの使用
- アレイ演算, 条件付きステートメントにおけるアレイの使用
- アレイメンバーシップのテスト, 条件付きステートメントにおけるアレイの使用
- 条件演算子
- 条件付き (conditional) ステートメント
- handlers, 条件付き (conditional) ステートメント
- 構文
- 概要
- アレイ, 連想アレイ
- 構文および形式
- printf(), Systemtap ハンドラー/ボディー
- SystemTap スクリプト
- 概要, SystemTap スクリプト
- SystemTap ハンドラーコンストラクト
- ハンドラー, 基本的な SystemTap ハンドラーコンストラクト
- 標準入力から、スクリプトを実行
- 標準入力からスクリプトを実行, SystemTap スクリプトの実行
- 無効な除算
- ランタイムエラー/警告
- SystemTap のエラーを理解する, ランタイムエラーおよび警告
- 特権のないスクリプト、コードが埋め込まれている
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
- 特権のないスクリプトにコードが埋め込まれている
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
- 特権のないスクリプトに安全でないコードが埋め込まれている
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
- 用途
- stap, SystemTap スクリプトの実行
- stapdev, SystemTap スクリプトの実行
- staprun, SystemTap スクリプトの実行
- stapusr, SystemTap スクリプトの実行
- 標準入力から、スクリプトを実行, SystemTap スクリプトの実行
- 目的、ドキュメント
- はじめに, 本ガイドの目的
- 着信 TCP 接続、監視
- SystemTap スクリプトの例, 着信 TCP 接続の監視
- 着信 TCP 接続の監視
- SystemTap スクリプトの例, 着信 TCP 接続の監視
- 着信/発信の関数呼び出し、追跡
- SystemTap スクリプトの例, 呼び出し先の追跡
- 着信/発信の関数呼び出しの追跡
- SystemTap スクリプトの例, 呼び出し先の追跡
- 空の一意のキー
- アレイからの値の読み取り
- アレイ演算, アレイからの値の読み取り
- 競合ユーザースペースのロック (futex 競合) の特定
- SystemTap スクリプトの例, 競合ユーザースペースのロックの特定
- 競合ユーザースペースのロック (futex 競合)、特定
- SystemTap スクリプトの例, 競合ユーザースペースのロックの特定
- 累積 I/O の監視
- SystemTap スクリプトの例, 累積 I/O の追跡
- 累積 I/O の追跡
- SystemTap スクリプトの例, 累積 I/O の追跡
- 累積 I/O、追跡
- SystemTap スクリプトの例, 累積 I/O の追跡
- 累積的仮想ファイルシステムの読み込み、集計
- アレイ内での複数要素の処理
- アレイ演算, アレイ内での複数要素の処理
- 統計集計
- アレイ演算, 統計集計の計算
- 統計集計が収集したデータの抽出
- 統計集計の計算
- アレイ演算, 統計集計の計算
- 統計集計の計算
- 統計集計への値の追加
- 統計集計の計算
- アレイ演算, 統計集計の計算
- 複数のコマンドライン引数、例
- SystemTap スクリプトの例, 呼び出し先の追跡
- 複数のコマンドライン引数の例
- SystemTap スクリプトの例, 呼び出し先の追跡
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
- 'foreach' 中に変数が修正される, 解析エラーとセマンティックエラー
- guru モード, 解析エラーとセマンティックエラー
- libdwfl 失敗, 解析エラーとセマンティックエラー
- スクリプトの文法的なエラー/誤字のエラー, 解析エラーとセマンティックエラー
- プローブの不一致, 解析エラーとセマンティックエラー
- プローブポイントに一致するものがない, 解析エラーとセマンティックエラー
- 変数/アレイに無効な値, 解析エラーとセマンティックエラー
- 特権のないスクリプトにコードが埋め込まれている, 解析エラーとセマンティックエラー
- 解決できないターゲット記号式, 解析エラーとセマンティックエラー
- 解決できない識別子のタイプ, 解析エラーとセマンティックエラー
- 解決できない関数呼び出し, 解析エラーとセマンティックエラー
- 記号やアレイに期待されているインデックス式, 解析エラーとセマンティックエラー
- 識別子タイプの不一致, 解析エラーとセマンティックエラー
- 非グローバルアレイ, 解析エラーとセマンティックエラー
- 解決できないターゲット記号式
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
- 解決できない識別子のタイプ
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
- 解決できない関数呼び出し
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
- 記号やアレイに期待されているインデックス式
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
- 設定とインストール, インストールと設定
- 識別子タイプの不一致
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
- 連想アレイ
- 関数, Systemtap ハンドラー/ボディー
- cpu(), Systemtap ハンドラー/ボディー
- ctime(), Systemtap ハンドラー/ボディー
- gettimeofday_s(), Systemtap ハンドラー/ボディー
- pp(), Systemtap ハンドラー/ボディー
- SystemTap スクリプト
- 概要, SystemTap スクリプト
- target(), Systemtap ハンドラー/ボディー
- thread_indent(), Systemtap ハンドラー/ボディー
- tid(), Systemtap ハンドラー/ボディー
- uid(), Systemtap ハンドラー/ボディー
- 関数 (ハンドラーで使用)
- exit(), Systemtap ハンドラー/ボディー
- 関数呼び出し (着信/発信)、追跡
- SystemTap スクリプトの例, 呼び出し先の追跡
- 関数呼び出し (解決できない)
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
- 関数呼び出し、集計
- SystemTap スクリプトの例, 関数呼び出しのカウント
- 関数呼び出しのカウント
- SystemTap スクリプトの例, 関数呼び出しのカウント
- 関数呼び出しの集計
- SystemTap スクリプトの例, 関数呼び出しのカウント
- 関連する値
- 概要
- アレイ, 連想アレイ
- 関連する値の割り当て
- アレイ演算, 関連する値の割り当て
- タイムスタンプをプロセス名に関連付ける, 関連する値の割り当て
- タイムスタンプをプロセス名に関連付ける
- アレイ演算, 関連する値の割り当て
- 関連する値の増加
- 集計 (統計)
- アレイ演算, 統計集計の計算
- 非グローバルアレイ
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
- 非同期イベント
- イベント, イベント
A
- aggregate element not found
- ランタイムエラー/警告
- SystemTap のエラーを理解する, ランタイムエラーおよび警告
- aggregation overflow
- ランタイムエラー/警告
- SystemTap のエラーを理解する, ランタイムエラーおよび警告
B
- begin
- イベント, イベント
C
- CONFIG_HZ、計算, 変数
- count 演算子
- 統計集計の計算
- array (演算子), 統計集計の計算
- CPU ティック
- SystemTap スクリプトの例, カーネルおよびユーザースペースで費やした時間の判定
- cpu()
- cross-compiling, 他のコンピューター用のインストルメンテーション生成
- ctime()
- ctime()、使用例
- スクリプトの例, ディスク読み取り/書き込みトラフィックの要約
D
- Delete 演算子
- アレイ/アレイ要素の消去
- アレイ演算, アレイおよびアレイ要素の消去/削除
- division by 0
- ランタイムエラー/警告
- SystemTap のエラーを理解する, ランタイムエラーおよび警告
E
- end
- イベント, イベント
- example
- 概要
- アレイ, 連想アレイ
- exceeded MAXACTION
- ランタイムエラー/警告
- SystemTap のエラーを理解する, ランタイムエラーおよび警告
- exceeded MAXNESTING
- ランタイムエラー/警告
- SystemTap のエラーを理解する, ランタイムエラーおよび警告
- exit()
F
- For ループ
- 条件付き (conditional) ステートメント
- ハンドラー, 条件付き (conditional) ステートメント
- foreach
- アレイ内での複数要素の処理
- アレイ演算, アレイ内での複数要素の処理
- foreach 出力の制限
- アレイ内での複数要素の処理
- アレイ演算, アレイ内での複数要素の処理
- foreach 出力の順序
- アレイ内での複数要素の処理
- アレイ演算, アレイ内での複数要素の処理
- format
- 概要
- アレイ, 連想アレイ
- futex システムコール
- SystemTap スクリプトの例, 競合ユーザースペースのロックの特定
- futex 競合、定義
- SystemTap スクリプトの例, 競合ユーザースペースのロックの特定
- futex 競合、特定
- SystemTap スクリプトの例, 競合ユーザースペースのロックの特定
G
- gettimeofday_s()
- global
- SystemTap ハンドラーコンストラクト
- ハンドラー, 変数
- guru モード
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
H
- handlers
- SystemTap ハンドラーコンストラクト
- global, 変数
I
- I/O の時間
- SystemTap スクリプトの例, ファイル読み取り/書き込みの I/O 時間の追跡
- I/O アクティビティーの出力 (累積)
- SystemTap スクリプトの例, 累積 I/O の追跡
- I/O トラフィック、要約
- スクリプトの例, ディスク読み取り/書き込みトラフィックの要約
- I/O 時間、監視
- SystemTap スクリプトの例, ファイル読み取り/書き込みの I/O 時間の追跡
- I/O 時間の監視
- SystemTap スクリプトの例, ファイル読み取り/書き込みの I/O 時間の追跡
- I/O 監視 (デバイスごと)
- SystemTap スクリプトの例, I/O 監視 (デバイスごと)
- if/else
- 条件付き (conditional) ステートメント
- ハンドラー, 条件付き (conditional) ステートメント
- if/else ステートメント、アレイの使用
- アレイ演算, 条件付きステートメントにおけるアレイの使用
- if/else 条件、代替の構文
- SystemTap スクリプトの例, ネットワークのプロファイリング
- inode 番号
- SystemTap スクリプトの例, ファイルの読み取りおよび書き込みの監視
L
- libdwfl 失敗
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
M
- MAXACTION exceeded
- ランタイムエラー/警告
- SystemTap のエラーを理解する, ランタイムエラーおよび警告
- MAXNESTING exceeded
- ランタイムエラー/警告
- SystemTap のエラーを理解する, ランタイムエラーおよび警告
- module("module")
- イベント, イベント
N
- name
- ローカル変数, Systemtap ハンドラー/ボディー
- net/socket.c、関数の追跡
- SystemTap スクリプトの例, ネットワークソケットコードで呼び出された関数の追跡
- number of errors: N, skipped probes: M
- ランタイムエラー/警告
- SystemTap のエラーを理解する, ランタイムエラーおよび警告
O
- operations
- アレイ/アレイ要素の消去, アレイおよびアレイ要素の消去/削除
- Delete 演算子, アレイおよびアレイ要素の消去/削除
- 仮想ファイルシステムの読み込み (累積的以外)、集計, アレイおよびアレイ要素の消去/削除
- 同一プローブ内の複数のアレイ演算, アレイおよびアレイ要素の消去/削除
- アレイおよびアレイ要素の削除, アレイおよびアレイ要素の消去/削除
- アレイからの値の読み取り, アレイからの値の読み取り
- シンプルな計算でのアレイの使用, アレイからの値の読み取り
- タイムスタンプ差分の計算, アレイからの値の読み取り
- 空の一意のキー, アレイからの値の読み取り
- アレイ内での複数要素の処理, アレイ内での複数要素の処理
- foreach, アレイ内での複数要素の処理
- foreach 出力の制限, アレイ内での複数要素の処理
- foreach 出力の順序, アレイ内での複数要素の処理
- 反復、アレイ内の要素の処理, アレイ内での複数要素の処理
- 累積的仮想ファイルシステムの読み込み、集計, アレイ内での複数要素の処理
- アレイ内の複数要素, アレイ内での複数要素の処理
- 条件付きステートメント、アレイの使用, 条件付きステートメントにおけるアレイの使用
- アレイメンバーシップのテスト, 条件付きステートメントにおけるアレイの使用
- 統計集計の計算, 統計集計の計算
- 連想アレイ, SystemTap でのアレイ演算
- 関連する値の割り当て
- タイムスタンプをプロセス名に関連付ける, 関連する値の割り当て
- 関連する値の増加, 関連する値の増加
- 仮想ファイルシステムの読み込みの集計 (VFS 読み込み), 関連する値の増加
P
- pointer dereference fault
- ランタイムエラー/警告
- SystemTap のエラーを理解する, ランタイムエラーおよび警告
- pp()
- printf()
- 書式指定子, Systemtap ハンドラー/ボディー
- 書式文字列, Systemtap ハンドラー/ボディー
- 構文および形式, Systemtap ハンドラー/ボディー
S
- scripts
- 概要
- ステートメントブロック, SystemTap スクリプト
- プローブ, SystemTap スクリプト
- stap
- stap オプション, SystemTap スクリプトの実行
- stapdev
- 使用方法, SystemTap スクリプトの実行
- staprun
- 使用方法, SystemTap スクリプトの実行
- stapusr
- 使用方法, SystemTap スクリプトの実行
- stat -c、ファイルデバイス番号の決定 (整数形式)
- SystemTap スクリプトの例, ファイルの読み取りおよび書き込みの監視
- stat -c、全体デバイス番号の決定
- SystemTap スクリプトの例, I/O 監視 (デバイスごと)
- syscall.system_call
- イベント, イベント
- SystemTap のアーキテクチャー, アーキテクチャー
- SystemTap のエラーを理解する
- ランタイムエラー/警告, ランタイムエラーおよび警告
- aggregate element not found, ランタイムエラーおよび警告
- aggregation overflow, ランタイムエラーおよび警告
- division by 0, ランタイムエラーおよび警告
- MAXACTION exceeded, ランタイムエラーおよび警告
- MAXNESTING exceeded, ランタイムエラーおよび警告
- number of errors: N, skipped probes: M, ランタイムエラーおよび警告
- pointer dereference fault, ランタイムエラーおよび警告
- コピー障害, ランタイムエラーおよび警告
- 解析エラー/セマンティックエラー, 解析エラーとセマンティックエラー
- 'foreach' 中に変数が修正される, 解析エラーとセマンティックエラー
- guru モード, 解析エラーとセマンティックエラー
- libdwfl 失敗, 解析エラーとセマンティックエラー
- スクリプトの文法的なエラー/誤字のエラー, 解析エラーとセマンティックエラー
- プローブの不一致, 解析エラーとセマンティックエラー
- プローブポイントに一致するものがない, 解析エラーとセマンティックエラー
- 変数/アレイに無効な値, 解析エラーとセマンティックエラー
- 特権のないスクリプトにコードが埋め込まれている, 解析エラーとセマンティックエラー
- 解決できないターゲット記号式, 解析エラーとセマンティックエラー
- 解決できない識別子のタイプ, 解析エラーとセマンティックエラー
- 解決できない関数呼び出し, 解析エラーとセマンティックエラー
- 記号やアレイに期待されているインデックス式, 解析エラーとセマンティックエラー
- 識別子タイプの不一致, 解析エラーとセマンティックエラー
- 非グローバルアレイ, 解析エラーとセマンティックエラー
- SystemTap の作動方法, SystemTap の作動方法
- SystemTap セッション, アーキテクチャー
- アーキテクチャー, アーキテクチャー
- イベントおよびハンドラー, SystemTap の作動方法
- イベントタイプ, SystemTap の作動方法
- SystemTap の使用, SystemTap の使用
- SystemTap の実行に必要な RPM, 必要なカーネル情報パッケージのインストール
- SystemTap の実行に必要なパッケージ, 必要なカーネル情報パッケージのインストール
- SystemTap の機能
- はじめに, SystemTap の機能
- SystemTap アーキテクチャー, アーキテクチャー
- SystemTap スクリプト
- 便利な例, 便利な SystemTap スクリプト
- 概要, SystemTap スクリプト
- イベントおよびハンドラー, SystemTap スクリプト
- コンポーネント, SystemTap スクリプト
- ステートメントブロック, SystemTap スクリプト
- プローブ, SystemTap スクリプト
- 形式および構文, SystemTap スクリプト
- 関数, SystemTap スクリプト
- SystemTap スクリプト、実行方法, SystemTap スクリプトの実行
- SystemTap スクリプトからインストルメンテーション/カーネルモジュールをコンパイルする, 他のコンピューター用のインストルメンテーション生成
- SystemTap スクリプトからインストルメンテーションモジュール、構築する, 他のコンピューター用のインストルメンテーション生成
- SystemTap スクリプトからインストルメンテーションモジュールを構築する, 他のコンピューター用のインストルメンテーション生成
- SystemTap スクリプトからカーネルモジュール、構築する, 他のコンピューター用のインストルメンテーション生成
- SystemTap スクリプトからカーネルモジュールを構築する, 他のコンピューター用のインストルメンテーション生成
- SystemTap スクリプトの例, 便利な SystemTap スクリプト
- CPU ティック, カーネルおよびユーザースペースで費やした時間の判定
- ctime()、使用例, ディスク読み取り/書き込みトラフィックの要約
- futex システムコール, 競合ユーザースペースのロックの特定
- I/O 時間の監視, ファイル読み取り/書き込みの I/O 時間の追跡
- if/else 条件、代替の構文, ネットワークのプロファイリング
- inode 番号, ファイルの読み取りおよび書き込みの監視
- net/socket.c、関数の追跡, ネットワークソケットコードで呼び出された関数の追跡
- stat -c、ファイルデバイス番号の決定 (整数形式), ファイルの読み取りおよび書き込みの監視
- stat -c、全体デバイス番号の決定, I/O 監視 (デバイスごと)
- thread_indent()、サンプル使用例, 呼び出し先の追跡
- timer.ms()、サンプル使用例, 関数呼び出しのカウント
- timer.s()、サンプル使用例, ポーリングアプリケーションの監視, 最もよく使われるシステムコールの追跡
- trigger function, 呼び出し先の追跡
- usrdev2kerndev(), I/O 監視 (デバイスごと)
- カーネルおよびユーザースペースで費やした時間の判定, カーネルおよびユーザースペースで費やした時間の判定
- システムコールの監視, 最もよく使われるシステムコールの追跡
- システムコールの監視 (プロセスごとのボリューム), プロセスごとのシステムコールボリュームの追跡
- ディスク I/O トラフィックの要約, ディスク読み取り/書き込みトラフィックの要約
- デバイス I/O の監視, I/O 監視 (デバイスごと)
- ネットワークのプロファイリング, ネットワークのプロファイリング, カーネルでのネットワークパケットドロップの監視
- ネットワークソケットコードで呼び出された関数の追跡, ネットワークソケットコードで呼び出された関数の追跡
- ファイルの読み取りおよび書き込みの監視, ファイルの読み取りおよび書き込みの監視
- ファイルデバイス番号 (整数形式), ファイルの読み取りおよび書き込みの監視
- ファイル属性の変更の監視, ファイル属性の変更の監視
- プロセスのデッドロック (futex 競合により発生), 競合ユーザースペースのロックの特定
- ポーリングアプリケーションの監視, ポーリングアプリケーションの監視
- 全体デバイス番号 (コマンドライン引数として使用), I/O 監視 (デバイスごと)
- 呼び出し先の追跡, 呼び出し先の追跡
- 着信 TCP 接続の監視, 着信 TCP 接続の監視
- 競合ユーザースペースのロック (futex 競合) の特定, 競合ユーザースペースのロックの特定
- 累積 I/O の追跡, 累積 I/O の追跡
- 複数のコマンドライン引数、例, 呼び出し先の追跡
- 関数呼び出しの集計, 関数呼び出しのカウント
- SystemTap スクリプトの実行
- SystemTap スクリプト関数, Systemtap ハンドラー/ボディー
- SystemTap ステートメント
- SystemTap ハンドラーコンストラクト
- global, 変数
- コマンドラインの引数, コマンドラインの引数
- 変数, 変数
- 条件付き (conditional) ステートメント, 条件付き (conditional) ステートメント
- For ループ, 条件付き (conditional) ステートメント
- if/else, 条件付き (conditional) ステートメント
- While ループ, 条件付き (conditional) ステートメント
- 条件演算子, 条件付き (conditional) ステートメント
- SystemTap セッション, アーキテクチャー
- SystemTap ハンドラー
- SystemTap ハンドラーコンストラクト, 基本的な SystemTap ハンドラーコンストラクト
- 構文および形式, 基本的な SystemTap ハンドラーコンストラクト
- systemtap パッケージ, SystemTap のインストール
- systemtap-runtime パッケージ, SystemTap のインストール
- systemtap-testsuite パッケージ
- サンプルスクリプト, 便利な SystemTap スクリプト
T
- Tapsets
- 定義, Tapsets
- target()
- TCP 接続 (着信)、監視
- SystemTap スクリプトの例, 着信 TCP 接続の監視
- thread_indent()
- thread_indent()、サンプル使用例
- SystemTap スクリプトの例, 呼び出し先の追跡
- tid()
- timer イベント
- イベント, イベント
- timer.ms()、サンプル使用例
- SystemTap スクリプトの例, 関数呼び出しのカウント
- timer.s()、サンプル使用例
- SystemTap スクリプトの例, ポーリングアプリケーションの監視, 最もよく使われるシステムコールの追跡
- tracepoint, イベント, カーネルでのネットワークパケットドロップの監視
- trigger function
- SystemTap スクリプトの例, 呼び出し先の追跡
U
- uid()
- uname -m, 必要なカーネル情報パッケージのインストール
- uname -r, 必要なカーネル情報パッケージのインストール
- usrdev2kerndev()
- SystemTap スクリプトの例, I/O 監視 (デバイスごと)
W
- While ループ
- 条件付き (conditional) ステートメント
- ハンドラー, 条件付き (conditional) ステートメント