SystemTap ビギナーズガイド
第1章 はじめに
netstat、ps、top、および iostat などのツールの出力に似た情報を提供します。ただし SystemTap は、収集した情報に対してより多くのフィルタリングと分析オプションを提供するように設計されています。
1.1. 本ガイドの目的
- ユーザーに SystemTap を紹介し、そのアーキテクチャーに慣れてもらい、全カーネルタイプの設定手順を提供します。
- 異なるコンポーネントのシステムで詳細なアクティビティーを監視するための事前作成された SystemTap スクリプトを提供し、それらの実行方法と出力の分析方法を提供します。
1.2. SystemTap の機能
- 柔軟性: SystemTap のフレームワークを使用すると、幅広いカーネル機能、システムコール、およびカーネルスペースで発生する他のイベントについて調査および監視目的のシンプルなスクリプトを開発できます。つまり、SystemTap は ツール というよりも、独自のカーネル固有のフォレンジックおよび監視ツールの開発を可能にするシステムといえます。
- 容易な使用: 上記で説明したように、SystemTap を使うことでユーザーはカーネルプロセスのインストルメント化、再コンパイル、インストール、および再起動という面倒なプロセスを経ずにカーネルスペースのイベントをプローブできるようになります。
top、OProfile、または ps など) ではネイティブで利用可能ではないシステムフォレンジックや監視機能の例になります。これらのスクリプトは SystemTap のアプリケーションの例を提供するために使われており、ユーザーは独自の SystemTap スクリプト作成時にこれらの機能を参考にすることができます。
第2章 SystemTap の使用
2.1. インストールと設定
重要
2.1.1. SystemTap のインストール
root で以下のコマンドを実行して systemtap と systemtap-runtime のパッケージをインストールします。
~]#yum install -y systemtap systemtap-runtime
2.1.2. 必要なカーネル情報パッケージのインストール
uname -m コマンドを実行すると判明します)。
debug リポジトリーから入手できます。
debug リポジトリーを有効にします。
~]#subscription-manager repos --enable=rhel-7-variant-debug-rpms
server、workstation、または client に置き換えます。バリアントを確認するには、以下のコマンドを実行します。
~]#cat /etc/redhat-releaseRed Hat Enterprise Linux Server release 7.2 (Maipo)
uname -r
3.10.0-327.el7.x86_643.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
yum パッケージマネージャーを使って、SystemTap を実行するために必要なパッケージを現行カーネルにインストールするには、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 が正常にデプロイされていれば、以下のような出力になります。
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 インストルメンテーションモジュールを使用するために各ターゲットマシンにインストールする必要があるのは 1 つのパッケージ systemtap-runtime のみです。
重要
注記
- インストルメンテーションモジュール
- SystemTap スクリプトから構築されるカーネルモジュールです。SystemTap モジュールはホストシステム上に構築され、ターゲットシステムのターゲットカーネルに読み込まれます。
- ホストシステム
- このシステム上で (SystemTap スクリプトから) インストルメンテーションモジュールがコンパイルされ、ターゲットシステム に読み込まれます。
- ターゲットシステム
- このシステム内で (SystemTap スクリプトから) インストルメンテーションモジュールが構築されます。
- ターゲットカーネル
- ターゲットシステムのカーネルです。このカーネルがインストルメンテーションモジュール の読み込み、実行を行います。
手順2.1 ホストシステムとターゲットシステムの設定
systemtap-runtimeパッケージを各ターゲットシステムにインストールします。- 各ターゲットシステムで
uname -rを実行して、ターゲットシステムで実行中のカーネルを確認します。 - SystemTap をホストシステムにインストールします。インストルメンテーションモジュールは、ホストシステム上でターゲットシステム用に構築されます。SystemTap のインストール方法については、「SystemTap のインストール」 を参照してください。
- 上記で判明したターゲットカーネルのバージョンを使用して、ターゲットカーネルと関連パッケージを 「必要なカーネル情報パッケージのインストール」 にある方法でホストシステムにインストールします。複数のターゲットシステムで異なるターゲットカーネルを使用している場合は、ターゲットシステムで使用しているカーネルごとにこのステップを繰り返します。
stap -r kernel_version script -m module_name -p4uname -r の出力)。script は、インストルメンテーションモジュールに変換されるスクリプトです。module_name は、希望する インストルメンテーションモジュールの名前です。
staprun module_name.kosimple.stp という名前の SystemTap スクリプトから 3.10.0-327.4.4.el7 ターゲットカーネル に simple.ko という インストルメンテーションモジュールを作成するには、以下のコマンドを実行します。
stap -r 2.6.32-53.el6 -e 'probe vfs.read {exit()}' -m simple -p4simple.ko という名前のモジュールが作成されます。simple.ko インストルメンテーションモジュール を使用するには、これをターゲットシステムにコピーして、(ターゲットシステム上で) 以下のコマンドを実行します。
staprun simple.ko2.3. SystemTap スクリプトの実行
stap コマンドで実行されます。stap を使うと、SystemTap スクリプトを標準入力またはファイルから実行できます。
stap と staprun を実行するには、システム対する権限の昇格が必要になります。ただし、すべてのユーザーが SystemTap 実行のために root アクセスを付与されるわけではありません。たとえば、権限のないユーザーが自身のマシン上で SystemTap インストルメンテーションを実行する必要がある場合もあります。
root アクセスなしで SystemTap を実行できるようにするには、そのユーザーを以下の両方のユーザーグループに追加します。
- stapdev
- このグループのメンバーは
stapを使用して SystemTap スクリプトを実行したり、staprunを使用して SystemTap インストルメンテーションモジュールを実行することができます。stapの実行では、SystemTap スクリプトがカーネルモジュールにコンパイルされ、それがカーネルに読み込まれます。これには権限の昇格が必要となり、stapdevメンバーにはそれが付与されます。ただし、この権限は実質的にはrootアクセスをstapdevメンバーに付与することになります。このため、stapdevグループのメンバーシップは、rootアクセスを信頼して付与できるメンバーにのみ許可してください。 - stapusr
- このグループのメンバーは
staprunを使って SystemTap インストルメンテーションモジュールの実行ができるだけです。また、このモジュールの実行が可能なのは、/lib/modules/kernel_version/systemtap/からのみです。このディレクトリーを所有できるのはrootユーザーのみで、書き込みが可能なのもrootユーザーのみとする必要があることに注意してください。
注記
stap で使用する一般的なオプションには、以下のものがあります。
- -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ではなく/bin/cp(stap script -c /bin/cpにあるように) のように、完全パスを使用する必要があります。target()に関する詳細情報は、SystemTap 関数 を参照してください。 -e 'script'- systemtap 翻訳の入力に、ファイルではなく
script文字列を使用します。 -F- SystemTap のフライトレコーダーモードを使用し、スクリプトをバックグラウンドプロセスにします。フライトレコーダーモードについての詳細は、「SystemTap フライトレコーダーモード」 を参照してください。
stap は、- スイッチを使用して標準入力からスクリプトを実行するように指示することもできます。例を示します。
例2.1 標準入力からスクリプトを実行
echo "probe timer.s(1) {exit()}" | stap -echo が標準入力に渡したスクリプトを stap に実行するように指示しています。stap で使用するオプションはすべて、- スイッチの前に挿入します。例2.1「標準入力からスクリプトを実行」 をより詳細な出力にするには、以下のようなコマンドになります。
echo "probe timer.s(1) {exit()}" | stap -v -stap についての詳細は、man stap を参照してください。
staprun を使用します。staprun およびクロスインストルメンテーションについての詳細は、「他のコンピューター用のインストルメンテーション生成」 を参照してください。
注記
stap options -v and -o also work for staprun. For more information about staprun, see the staprun(1) manual page.
2.3.1. SystemTap フライトレコーダーモード
-F オプション) は、生成される出力の量を制限します。フライトレコーダーモードには、メモリー内モードとファイルモードという 2 種類があります。どちらの場合も、SystemTap スクリプトはバックグラウンドプロセスとして実行されます。
2.3.1.1. メモリー内フライトレコーダー
-F オプション) をファイル名なしで使用すると、SystemTap はカーネルメモリー内のバッファーを使用してスクリプトの出力を保存します。次に、SystemTap インストルメンテーションモジュールが読み込まれてプローブが開始し、インストルメンテーションが外されてバックグラウンドに置かれます。関心のあるイベントが発生すると、インストルメンテーションは再度アタッチされ、メモリーバッファー内の最近の出力と継続中の出力が閲覧可能となります。以下のコマンドでは、フライトレコーダーのメモリー内モードを使ってスクリプトが開始されます。
stap -F /usr/share/doc/systemtap-version/examples/io/iotime.stpDisconnecting 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.stpSIGTERM を送信すると、SystemTap スクリプトはシャットダウンし、データ収集が停止されます。たとえば、以前のコマンドでプロセス ID が 7590 となっている場合、以下のコマンドを実行すると SystemTap スクリプトはシャットダウンします。
kill -s SIGTERM 7590ls -sh /tmp/pfaults.log.* を実行して表示されるのは、2 ファイルのみです。
1020K /tmp/pfaults.log.5 44K /tmp/pfaults.log.6/tmp/pfaults.log.6 になります。
第3章 SystemTap の作動方法
3.1. アーキテクチャー
手順3.1 SystemTap セッション
- まず、SystemTap が既存の tapset ライブラリー (通常は
/usr/share/systemtap/tapset/ディレクトリー内) の使用された tapsets に対してスクリプトをチェックします。次に SystemTap は見つかった tapset を tapset ライブラリー内の対応する定義で置き換えます。 - SystemTap はスクリプトを C に変換し、システム C コンパイラーを実行してそこからカーネルモジュールを作成します。このステップを実行するツールは、systemtap パッケージに含まれています (詳細は 「SystemTap のインストール」 を参照してください)。
- SystemTap はモジュールを読み込み、スクリプト内の全プローブ (イベントおよびハンドラー) を有効にします。systemtap-runtime パッケージ内の
staprunがこの機能を提供します (詳細は 「SystemTap のインストール」 を参照してください)。 - イベントが発生すると、それに対応するハンドラーが実行されます。
- SystemTap セッションが終了すると、プローブは無効になり、カーネルモジュールは読み込み解除されます。
stap. This program is SystemTap's main front-end tool. For more information about stap, see the stap(1) manual page (once SystemTap is properly installed on your machine).
3.2. SystemTap スクリプト
注記
probe event {statements},) で区切ります。1 つのプローブで複数のイベントが指定された場合、SystemTap は指定されたイベントが発生するとそのハンドラーを実行します。
{ }) で囲まれており、イベントごとに実行されるステートメントが含まれています。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(ミリ秒)timer.us(マイクロ秒)timer.ns(ナノ秒)timer.hz(ヘルツ)timer.jiffies(jiffies)
timer イベントを情報を収集する他のプローブと併せて使用すると、定期的な更新が表示でき、その情報の変遷が分かります。
重要
3.2.2. Systemtap ハンドラー/ボディ
例3.4 helloworld.stp
probe begin
{
printf ("hello world\n")
exit ()
}
begin イベント (セッションの開始) が { } で囲まれているハンドラーを始動させます。これは単に hello world をプリントして改行し、終了するものです。
printf() ステートメントは、データをプリントする最も簡単な関数の 1 つです。printf() を以下の書式で使用すると、多くの SystemTap 関数を使用するデータを表示できます。
printf ("format string\n", arguments)
hello world のプリントを指示するだけで、書式は指定していません。
%s (文字列用) や %d (数字用) といった書式指定子を format string に使用することもできます。format string には複数の書式指定子を使用することが可能で、それぞれを対応する引数に一致させます。複数の引数はコンマ (,) で区切ります。
注記
例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 は、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 IDstap 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 ハンドラーコンストラクト
awk 構文に基づいています。本セクションでは、SystemTap ハンドラーコンストラクトで最も有用なものをいくつか説明します。これで、簡潔かつ便利な 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 増やすために使用されます。以下のプローブでは、100 jiffies ごとに count_jiffies が 1 増えます。
probe timer.jiffies(100) { count_jiffies ++ }count_jiffies が整数であると理解します。count_jiffies には初期値が割り当てられていないことから、デフォルトでは初期値はゼロになります。
3.3.2. 条件付き (conditional) ステートメント
- If/Else ステートメント
- 書式は以下のようになります。
if (condition) statement1 else statement2
statement1は、condition式がゼロ以外の場合に実行されます。statement2は、condition式がゼロの場合に実行されます。else節 (elsestatement2) はオプションです。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 { }
stap commandlineargs.stp kernel function のように) プローブするカーネル関数をコマンドライン引数として渡すことができる点が異なります。また、@1、@2 のようにユーザーが入力した順番で複数のコマンドライン引数をスクリプトが受け付けるように指定することもできます。
3.4. 連想アレイ
global 変数として宣言されるべきです。連想アレイ内の要素にアクセスする構文は awk の構文と似ており、以下のようになります。
array_name[index_expression]
array_name は、アレイが使用する任意の名前になります。index_expression は、アレイ内の特定の一意の鍵を見るために使用されます。例として、tom、dick、および harry という 3 人の年齢 (一意の鍵) を指定する、arr という名前のアレイを構築してみましょう。3 人に割り当てる年齢 (関連する値) をそれぞれ 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 を返す際 (つまり、gnome-terminal が初めて VFS 読み込みを実行する際)、そのプロセス名は一意の鍵 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. 統計集計 (Statistical Aggregates) の計算
<<< 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
- variable/array index expression に保存されたすべての値の数を返します。例3.19「stat-aggregates.stp」 のサンプルプローブでは、
@count(writes[execname()])の式は、アレイwritesの各一意の鍵に保存されている値の数を返します。 - sum
- variable/array index expression に保存されたすべての値の合計を返します。例3.19「stat-aggregates.stp」 のサンプルプローブでは、
@sum(writes[execname()])の式は、アレイwritesの各一意の鍵に保存されている値すべての合計を返します。 - min
- variable/array index expression に保存されているすべての値で最も小さいものを返します。
- max
- variable/array index expression に保存されているすべての値で最も大きいものを返します。
- avg
- variable/array index expression に保存されているすべての値の平均を返します。
例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 を使用します。tapsets 標準ライブラリーは、デフォルトで /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 or 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 関数 の 例3.6「thread_indent.stp」 と同じ ものです。
例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]
}
$count を使ってシステムコールが読み取りまたは書き込みを 試みた データ量 (バイト単位) も追跡します。( 「ディスク読み取り/書き込みトラフィックの要約」 の 例4.9「disktop.stp」 で使用されている) $return は、実際に 読み取り/書き込みされたデータ量を保存することに注意してください。$count を使用できるのは、(syscall.read や syscall.write など) データの読み取りや書き込みを追跡するプローブのみです。
例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 KiB4.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)
}
stat -c "0x%D" directory を使用します。ここでの directory は、監視するデバイス上にあるものにします。
usrdev2kerndev() 関数は、全体デバイス番号をカーネルが理解する書式に変換します。usrdev2kerndev() による出力は、MKDEV()、MINOR()、および MAJOR() の関数と併せて、特定デバイスのメジャーおよびマイナー番号の決定に使用されます。
vfs_read または vfs_write)、およびカーネルデバイス番号が含まれます。
stap traceio2.stp 0x805 の出力の抜粋です。ここでの 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番号。
stat -c '%D %i' filename を使用します。ここでの filename は、絶対パスになります。
/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 接頭辞は、ベース 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()
}
stap functioncallcount.stp "*@mm/*.c" の出力抜粋になります。
例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 関数 のエントリーを参照してください。
stap para-callgraph.stp 'kernel.function("*@fs/*.c")' 'kernel.function("sys_read")' の出力抜粋例になります。
例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=0xffff8801116ce9804.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
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])
}
}
pollselectepollitimerfutexnanosleepsignal
例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| iscsidtimer.s()) を編集すると、サンプル時間を長くすることができます。例4.21「functioncallcount.stp」 の出力には、上位 20 位のポーリングアプリケーションの名前と UID、各アプリケーションがシステムコールのポーリングを行った回数が含まれています。例4.28「例4.27「timeout.stp」 のサンプル出力」 はスクリプトの抜粋になります。
4.3.5. 最もよく使われるシステムコールの追跡
pollselectepollitimerfutexnanosleepsignal
例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)
}
timer.s() プローブを追加して、一定時間後に終了させることもできます。たとえば、5 秒後にスクリプトを終了させるには、以下のプローブをスクリプトに追加します。
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 のエラーを理解する
5.1. 解析エラーとセマンティックエラー
スクリプトに文法的なエラーまたは誤字や脱字のエラーが含まれています。SystemTap は間違ったコンストラクトのタイプを検出しプローブのコンテキストを表示します。
probe vfs.read probe vfs.write
probe キーワードには別の値を期待していたことを示すエラーメッセージが表示されます。
parse error: expected one of '. , ( ? ! { = +='
saw: keyword at perror.stp:2:1
1 parse error(s).
スクリプトには危険な埋め込み C コードが含まれています (%{ %} で囲まれたコードブロック)。SystemTap では目的にあった tapsets がない場合にはスクリプトに C コードを埋め込むことができるため便利ですが、埋め込みの C コンストラクトは安全ではありません。スクリプトにこのような構造を検出すると SystemTap はこのエラーで警告を発します。
stapdev グループのメンバーである (または root 特権がある) 場合には、-g オプションを使って guru モードでスクリプトを実行します。
stap -g script
スクリプト内の 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())
}
識別子 (変数など) が使用されているがタイプ (整数または文字列) を特定できません。たとえば、printf ステートメントに変数を使用しているのにスクリプトでは変数に値を割り当てていない場合などにこのエラーが発生します。
SystemTap ではアレイ内の場所や変数に値を割り当てることはできません。割り当ての目的地が有効な目的地になっていません。次のようなコードを使用するとこのエラーが発生することになります。
probe begin { printf("x") = 1 }
スクリプト内の関数コールまたはアレイインデックス式が無効な数の引数/パラメーターを使用しました。SystemTap では、arity (アリティ) はアレイのインデックス数か関数へのパラメーター数を見ることができます。
アレイをグローバル変数と宣言せずに、スクリプトがアレイ演算を使用しました (グローバル変数は、SystemTap スクリプトでの使用後に宣言されることができます)。アレイが一貫性のないアリティと使用されると、同様のメッセージが表示されます。
var アレイがアクティブな foreach ループ内で修正されています (割り当てられるまたは削除される)。このエラーは、スクリプト内の演算が foreach ループ内で関数コールを実行しても表示されます。
SystemTap は、イベントまたは SystemTap 関数 pnt が参照しているものを理解できませんでした。これは通常、SystemTap が tapset ライブラリー内で pnt にマッチするものを見つけられなかったことを意味します。ここでの N は、エラーの行とコラムを指します。
pnt イベントとハンドラー関数が各種の理由で解決できませんでした。このエラーは、スクリプトに kernel.function("name") イベントが含まれ、name が存在しない場合に発生します。このエラーはスクリプトに無効なカーネルファイル名やソース行数が含まれていることを意味する場合もあります。
スクリプトのハンドラーはターゲット変数を参照しますが、変数の値が解決できませんでした。このエラーは、ハンドラーがターゲット変数を参照した際にその変数がコンテキスト内で無効であることも意味します。これは、生成されたコードのコンパイラー最適化の結果である可能性もあります。
デバッグ情報の処理に問題がありました。ほとんどの場合、このエラーは kernel-debuginfo パッケージのインストールにより発生します。インストールされた kernel-debuginfo パッケージ自体に一貫性もしくは正確性の問題がある可能性があります。
SystemTap は適切な kernel-debuginfo を見つけることができませんでした。
5.2. ランタイムエラーおよび警告
エラー、プローブのスキップ、もしくはこれら両方が実行中に発生しました。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
stapprobesman ページでは SystemTap で対応している各種のプローブポイントおよび SystemTap tapset ライブラリーで定義している他のエイリアスについて紹介しています。man ページの下の方にはstapprobes.scsi、stapprobes.kprocess、stapprobes.signalなど特定のシステムコンポーネント用に似たようなプローブポイントを列挙している別の man ページの一覧があります。- man stapfuncs
stapfuncsman ページは SystemTap tapset ライブラリーで対応している多数の関数および各関数に規定の構文について説明しています。ただし、対応している関数が すべて記載されているわけではない ので注意してください。説明がない関数が他にもあります。- SystemTap Language Reference (SystemTap 言語リファレンス)
- SystemTap の言語構成および構文がすべて記載されているリファレンスです。C++ および似たようなプログラミング言語についての基本的な知識または中程度の知識をお持ちのユーザーを対象としています。『SystemTap Language Reference』 は http://sourceware.org/systemtap/langref/ で公開されています。
- Tapset Developers Guide
- SystemTap スクリプトの記述に熟達したら独自のタップセットの記述に挑戦することができます。『Tapset Developers Guide』 ではタップセットライブラリーに関数を追加する方法について説明しています。
- testsuite (テストスイート)
systemtap-testsuiteパッケージを使用するとソースから構築しなくても SystemTap ツールチェーン全体の検証を行うことができます。また、研究や検証対象となる SystemTap スクリプトのサンプルも数多く収納されています。一部のサンプルスクリプトについては 4章便利な SystemTap スクリプト で説明していますsystemtap-testsuiteに収納されているサンプルスクリプトは、デフォルトでは/usr/share/systemtap/testsuite/systemtap.examplesに格納されています。
付録A 改訂履歴
| 改訂履歴 | |||
|---|---|---|---|
| 改訂 1-8.2 | Mon Jul 3 2017 | ||
| |||
| 改訂 1-8.1 | Wed Mar 1 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 の機能
- パフォーマンス監視, はじめに
- 本ガイドの目的, 本ガイドの目的
- 目的、本ガイド, 本ガイドの目的
- アレイ, 連想アレイ
- (参照 連想アレイ)
- アレイ/アレイ要素の消去
- アレイ演算, アレイおよびアレイ要素の消去/削除
- delete 演算子, アレイおよびアレイ要素の消去/削除
- アレイおよびアレイ要素の消去
- アレイ演算
- 仮想ファイルシステム reads (非累積的)、集計 , アレイおよびアレイ要素の消去/削除
- 同一プローブ内での複数アレイ演算, アレイおよびアレイ要素の消去/削除
- アレイからの値の読み取り
- アレイ演算, アレイからの値の読み取り
- シンプルな計算でのアレイの使用, アレイからの値の読み取り
- 空の一意の鍵, アレイからの値の読み取り
- タイムスタンプ差分の計算
- アレイ演算, アレイからの値の読み取り
- アレイを使った代数公式
- アレイからの値の読み取り
- アレイ演算, アレイからの値の読み取り
- アレイメンバーシップのテスト
- 条件付きステートメント、アレイの使用
- アレイ演算, 条件付きステートメントにおけるアレイの使用
- アレイローカルがサポートされない
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
- アレイ内の複数要素
- アレイ演算, アレイ内での複数要素の処理
- アレイ内の複数要素の処理
- foreach
- アレイ演算, アレイ内での複数要素の処理
- foreach 出力の制限
- アレイ演算, アレイ内での複数要素の処理
- foreach 出力の指示
- アレイ演算, アレイ内での複数要素の処理
- アレイ演算, アレイ内での複数要素の処理
- 累積的仮想ファイルシステムの読み取り、計算
- アレイ演算, アレイ内での複数要素の処理
- アレイ演算
- アレイおよびアレイ要素の削除, アレイおよびアレイ要素の消去/削除
- アレイおよびアレイ要素の消去, アレイおよびアレイ要素の消去/削除
- delete 演算子, アレイおよびアレイ要素の消去/削除
- 仮想ファイルシステム reads (非累積的)、集計 , アレイおよびアレイ要素の消去/削除
- 同一プローブ内での複数アレイ演算, アレイおよびアレイ要素の消去/削除
- アレイからの値の読み取り, アレイからの値の読み取り
- シンプルな計算でのアレイの使用, アレイからの値の読み取り
- タイムスタンプ差分の計算, アレイからの値の読み取り
- 空の一意の鍵, アレイからの値の読み取り
- アレイ内の複数要素, アレイ内での複数要素の処理
- アレイ内の複数要素の処理, アレイ内での複数要素の処理
- foreach, アレイ内での複数要素の処理
- foreach 出力の制限, アレイ内での複数要素の処理
- foreach 出力の指示, アレイ内での複数要素の処理
- 反復、アレイ内で要素を処理する, アレイ内での複数要素の処理
- 累積的仮想ファイルシステムの読み取り、計算, アレイ内での複数要素の処理
- 条件付きステートメント、アレイの使用, 条件付きステートメントにおけるアレイの使用
- アレイメンバーシップのテスト, 条件付きステートメントにおけるアレイの使用
- 統計集計の計算, 統計集計 (Statistical Aggregates) の計算
- @avg (整数抽出), 統計集計 (Statistical Aggregates) の計算
- @count (整数抽出), 統計集計 (Statistical Aggregates) の計算
- @max (整数抽出), 統計集計 (Statistical Aggregates) の計算
- @min (整数抽出), 統計集計 (Statistical Aggregates) の計算
- @sum (整数抽出), 統計集計 (Statistical Aggregates) の計算
- count (演算子), 統計集計 (Statistical Aggregates) の計算
- 統計集計が収集したデータの抽出, 統計集計 (Statistical Aggregates) の計算
- 統計集計への値の追加, 統計集計 (Statistical Aggregates) の計算
- 連想アレイ, 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 スクリプト
- プローブ, 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, アーキテクチャー
- タイムスタンプ、プロセス名に関連付ける
- 関連する値の割り当て
- アレイ演算, 関連する値の割り当て
- タイムスタンプをプロセス名に関連付ける
- 関連する値の割り当て
- アレイ演算, 関連する値の割り当て
- タイムスタンプ差分、計算
- アレイからの値の読み取り
- アレイ演算, アレイからの値の読み取り
- タイムスタンプ差分の計算
- アレイからの値の読み取り
- アレイ演算, アレイからの値の読み取り
- ターゲットカーネル
- クロスインストルメンテーション, 他のコンピューター用のインストルメンテーション生成
- ターゲットシステム
- クロスインストルメンテーション, 他のコンピューター用のインストルメンテーション生成
- ターゲットシステムおよびホストシステム
- テスト、初期, 初期テスト
- ディスク I/O トラフィック、要約
- スクリプト例, ディスク読み取り/書き込みトラフィックの要約
- ディスク I/O トラフィックの要約
- スクリプト例, ディスク読み取り/書き込みトラフィックの要約
- デバイス I/O の監視
- SystemTap スクリプトの例, I/O 監視 (デバイスごと)
- デバイス I/O、監視
- SystemTap スクリプトの例, I/O 監視 (デバイスごと)
- ネットワークのプロファイリング
- SystemTap スクリプトの例, ネットワークのプロファイリング, カーネルでのネットワークパケットドロップの監視
- ネットワークソケットコード、呼び出された関数の追跡
- SystemTap スクリプトの例, ネットワークソケットコードで呼び出された関数の追跡
- ネットワークソケットコードで呼び出された関数、追跡
- 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 フライトレコーダーモード
- ファイルモード, ファイルフライトレコーダー
- メモリー内モード, メモリー内フライトレコーダー
- プロセスのデッドロック (futex 競合により発生)
- 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 の追跡
- 一意の鍵
- 導入
- アレイ, 連想アレイ
- 仮想ファイルシステム reads (累積的) 、集計
- アレイ内の複数要素の処理
- アレイ演算, アレイ内での複数要素の処理
- 仮想ファイルシステム reads (累積的)、集計
- アレイおよびアレイ要素の消去
- アレイ演算, アレイおよびアレイ要素の消去/削除
- 仮想ファイルシステムの読み込み (VFS 読み込み) の計算
- 関連する値の増加
- アレイ演算, 関連する値の増加
- 使用
- stap, SystemTap スクリプトの実行
- stapdev, SystemTap スクリプトの実行
- staprun, SystemTap スクリプトの実行
- stapusr, SystemTap スクリプトの実行
- SystemTap スクリプトの実行, SystemTap スクリプトの実行
- オプション、stap, SystemTap スクリプトの実行
- 標準入力、スクリプトを実行, SystemTap スクリプトの実行
- 例
- 導入
- アレイ, 連想アレイ
- 便利な SystemTap スクリプトの例, 便利な SystemTap スクリプト
- 値、の割り当て
- アレイ演算, 関連する値の割り当て
- 全体デバイス番号 (コマンドライン引数として使用)
- SystemTap スクリプトの例, I/O 監視 (デバイスごと)
- 初期テスト, 初期テスト
- 反復、アレイ内で要素を処理する
- アレイ内の複数要素の処理
- アレイ演算, アレイ内での複数要素の処理
- 同一プローブ内での複数アレイ演算
- アレイおよびアレイ要素の消去
- アレイ演算, アレイおよびアレイ要素の消去/削除
- 同期および非同期イベントの例
- イベント, イベント
- 同期イベント
- イベント, イベント
- 呼び出し先の追跡
- SystemTap スクリプトの例, 呼び出し先の追跡
- 変数
- SystemTap ハンドラーコンストラクト
- ハンドラー, 変数
- 変数 (ローカル)
- name, Systemtap ハンドラー/ボディ
- サンプル使用例
- $count, ファイル読み取り/書き込みの I/O 時間の追跡
- $return, ディスク読み取り/書き込みトラフィックの要約, 累積 I/O の追跡
- 変数やアレイに無効な値
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
- 必要なパッケージ, 必要なカーネル情報パッケージのインストール
- 整数抽出
- 統計集計の計算
- 書式
- 導入
- アレイ, 連想アレイ
- 書式および構文
- printf(), Systemtap ハンドラー/ボディ
- 書式と構文
- SystemTap スクリプト
- 導入, SystemTap スクリプト
- SystemTap ハンドラーコンストラクト
- ハンドラー, 変数
- 書式指定子
- printf(), Systemtap ハンドラー/ボディ
- 最も重いディスクの読み取り/書き込み、識別
- スクリプト例, ディスク読み取り/書き込みトラフィックの要約
- 最も重いディスクの読み取り/書き込みの識別
- スクリプト例, ディスク読み取り/書き込みトラフィックの要約
- 本ガイドの目的
- はじめに, 本ガイドの目的
- 条件付きステートメント、アレイの使用
- アレイ演算, 条件付きステートメントにおけるアレイの使用
- アレイメンバーシップのテスト, 条件付きステートメントにおけるアレイの使用
- 条件演算子
- 条件付きステートメント
- ハンドラー, 条件付き (conditional) ステートメント
- 構文
- 導入
- アレイ, 連想アレイ
- 構文および書式
- printf(), Systemtap ハンドラー/ボディ
- 構文と書式
- SystemTap ハンドラーコンストラクト
- ハンドラー, 基本的な SystemTap ハンドラーコンストラクト
- 構文と書式と
- SystemTap スクリプト
- 導入, SystemTap スクリプト
- 標準入力、スクリプトを実行
- 標準入力からスクリプトを実行, SystemTap スクリプトの実行
- 演算
- アレイおよびアレイ要素の削除, アレイおよびアレイ要素の消去/削除
- アレイおよびアレイ要素の消去, アレイおよびアレイ要素の消去/削除
- delete 演算子, アレイおよびアレイ要素の消去/削除
- 仮想ファイルシステム reads (非累積的)、集計 , アレイおよびアレイ要素の消去/削除
- 同一プローブ内での複数アレイ演算, アレイおよびアレイ要素の消去/削除
- アレイからの値の読み取り, アレイからの値の読み取り
- シンプルな計算でのアレイの使用, アレイからの値の読み取り
- タイムスタンプ差分の計算, アレイからの値の読み取り
- 空の一意の鍵, アレイからの値の読み取り
- アレイ内の複数要素, アレイ内での複数要素の処理
- アレイ内の複数要素の処理, アレイ内での複数要素の処理
- foreach, アレイ内での複数要素の処理
- foreach 出力の制限, アレイ内での複数要素の処理
- foreach 出力の指示, アレイ内での複数要素の処理
- 反復、アレイ内で要素を処理する, アレイ内での複数要素の処理
- 累積的仮想ファイルシステムの読み取り、計算, アレイ内での複数要素の処理
- 条件付きステートメント、アレイの使用, 条件付きステートメントにおけるアレイの使用
- アレイメンバーシップのテスト, 条件付きステートメントにおけるアレイの使用
- 統計集計の計算, 統計集計 (Statistical Aggregates) の計算
- @avg (整数抽出), 統計集計 (Statistical Aggregates) の計算
- @count (整数抽出), 統計集計 (Statistical Aggregates) の計算
- @max (整数抽出), 統計集計 (Statistical Aggregates) の計算
- @min (整数抽出), 統計集計 (Statistical Aggregates) の計算
- @sum (整数抽出), 統計集計 (Statistical Aggregates) の計算
- count (演算子), 統計集計 (Statistical Aggregates) の計算
- 統計集計が収集したデータの抽出, 統計集計 (Statistical Aggregates) の計算
- 統計集計への値の追加, 統計集計 (Statistical Aggregates) の計算
- 連想アレイ, SystemTap でのアレイ演算
- 関連する値の割り当て
- タイムスタンプをプロセス名に関連付ける, 関連する値の割り当て
- 関連する値の増加, 関連する値の増加
- 仮想ファイルシステムの読み込み (VFS 読み込み) の計算, 関連する値の増加
- 無効な除算
- ランタイムエラー/警告
- SystemTap のエラーを理解する, ランタイムエラーおよび警告
- 特権のないスクリプト、コードが埋め込まれている
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
- 特権のないスクリプトにコードが埋め込まれている
- 解析エラー/セマンティックエラー
- 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 の追跡
- 累積的仮想ファイルシステムの読み取り、計算
- アレイ内の複数要素の処理
- アレイ演算, アレイ内での複数要素の処理
- 統計集計
- 統計集計が収集したデータの抽出
- 統計集計の計算
- 統計集計の計算
- アレイ演算, 統計集計 (Statistical Aggregates) の計算
- @avg (整数抽出), 統計集計 (Statistical Aggregates) の計算
- @count (整数抽出), 統計集計 (Statistical Aggregates) の計算
- @max (整数抽出), 統計集計 (Statistical Aggregates) の計算
- @min (整数抽出), 統計集計 (Statistical Aggregates) の計算
- @sum (整数抽出), 統計集計 (Statistical Aggregates) の計算
- count (演算子), 統計集計 (Statistical Aggregates) の計算
- 統計集計が収集したデータの抽出, 統計集計 (Statistical Aggregates) の計算
- 統計集計への値の追加, 統計集計 (Statistical Aggregates) の計算
- 統計集計への値の追加
- 統計集計の計算
- 複数のコマンドライン引数、例
- SystemTap スクリプトの例, 呼び出し先の追跡
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
- 'foreach' 中に変数が修正される, 解析エラーとセマンティックエラー
- guru モード, 解析エラーとセマンティックエラー
- libdwfl 失敗, 解析エラーとセマンティックエラー
- スクリプトの文法的なエラー/誤字や脱字のエラー, 解析エラーとセマンティックエラー
- プローブのミスマッチ, 解析エラーとセマンティックエラー
- プローブポイントにマッチがない, 解析エラーとセマンティックエラー
- 変数やアレイに無効な値, 解析エラーとセマンティックエラー
- 特権のないスクリプトにコードが埋め込まれている, 解析エラーとセマンティックエラー
- 解決できないターゲット記号式, 解析エラーとセマンティックエラー
- 解決できない識別子タイプ, 解析エラーとセマンティックエラー
- 解決できない関数コール, 解析エラーとセマンティックエラー
- 記号やアレイに期待されているインデックス式, 解析エラーとセマンティックエラー
- 識別子タイプの不一致, 解析エラーとセマンティックエラー
- 非グローバルアレイ, 解析エラーとセマンティックエラー
- 解決できないターゲット記号式
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
- 解決できない識別子タイプ
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
- 解決できない関数コール
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
- 記号やアレイに期待されているインデックス式
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
- 設定とインストール, インストールと設定
- 識別子タイプの不一致
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
- 超過の MAXACTION
- ランタイムエラー/警告
- SystemTap のエラーを理解する, ランタイムエラーおよび警告
- 超過の MAXNESTING
- ランタイムエラー/警告
- 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 のエラーを理解する, ランタイムエラーおよび警告
- 非グローバルアレイ
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
- 非同期イベント
- イベント, イベント
A
- aggregate element not found
- ランタイムエラー/警告
- SystemTap のエラーを理解する, ランタイムエラーおよび警告
- aggregation overflow
- ランタイムエラー/警告
- SystemTap のエラーを理解する, ランタイムエラーおよび警告
B
- begin
- イベント, イベント
C
- CONFIG_HZ, computing for, 変数
- count 演算子
- 統計集計の計算
- array (演算子), 統計集計 (Statistical Aggregates) の計算
- CPU ティック
- SystemTap スクリプトの例, カーネルおよびユーザースペースで費やした時間の判定
- cpu()
- ctime()
- ctime()、使用例
- スクリプト例, ディスク読み取り/書き込みトラフィックの要約
D
- delete 演算子
- アレイおよびアレイ要素の消去
- アレイ演算, アレイおよびアレイ要素の消去/削除
- division by 0
- ランタイムエラー/警告
- SystemTap のエラーを理解する, ランタイムエラーおよび警告
F
- for ループ
- 条件付きステートメント
- ハンドラー, 条件付き (conditional) ステートメント
- foreach
- アレイ内の複数要素の処理
- アレイ演算, アレイ内での複数要素の処理
- foreach 出力の制限
- アレイ内の複数要素の処理
- アレイ演算, アレイ内での複数要素の処理
- foreach 出力の指示
- アレイ内の複数要素の処理
- アレイ演算, アレイ内での複数要素の処理
- format strings
- printf(), Systemtap ハンドラー/ボディ
- FS 読み込み、の計算
- 関連する値の増加
- アレイ演算, 関連する値の増加
- futex システムコール
- SystemTap スクリプトの例, 競合ユーザースペースのロックの特定
- futex 競合、定義
- SystemTap スクリプトの例, 競合ユーザースペースのロックの特定
- futex 競合、特定
- SystemTap スクリプトの例, 競合ユーザースペースのロックの特定
G
- gettimeofday_s()
- guru モード
- 解析エラー/セマンティックエラー
- SystemTap のエラーを理解する, 解析エラーとセマンティックエラー
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) ステートメント
- 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 のエラーを理解する, ランタイムエラーおよび警告
P
- pointer dereference fault
- ランタイムエラー/警告
- SystemTap のエラーを理解する, ランタイムエラーおよび警告
- pp()
- printf()
- 書式指定子, Systemtap ハンドラー/ボディ
- 書式文字列, Systemtap ハンドラー/ボディ
- 構文および書式, Systemtap ハンドラー/ボディ
S
- stap
- stap オプション, SystemTap スクリプトの実行
- stapdev
- staprun
- stapusr
- 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 ハンドラーコンストラクト
- グローバル, 変数
- コマンドラインの引数, コマンドラインの引数
- 変数, 変数
- 条件付き (conditional) ステートメント, 条件付き (conditional) ステートメント
- 条件付きステートメント
- for ループ, 条件付き (conditional) ステートメント
- if/else, 条件付き (conditional) ステートメント
- while ループ, 条件付き (conditional) ステートメント
- 条件演算子, 条件付き (conditional) ステートメント
- SystemTap セッション, アーキテクチャー
- SystemTap ハンドラー
- SystemTap ハンドラーコンストラクト, 基本的な SystemTap ハンドラーコンストラクト
- 構文および書式, 基本的な SystemTap ハンドラーコンストラクト
- systemtap パッケージ, SystemTap のインストール
- systemtap-runtime パッケージ, SystemTap のインストール
- systemtap-testsuite package
- サンプルスクリプト, 便利な 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 監視 (デバイスごと)
V
- vfs.file_operation
- イベント, イベント
W
- while ループ
- 条件付きステートメント
- ハンドラー, 条件付き (conditional) ステートメント
