ナビゲーションリンクをスキップ | |
印刷ビューの終了 | |
![]() |
マニュアルページセクション 1: ユーザーコマンド Oracle Solaris 11 Information Library (日本語) |
- システムコールとシグナルの追跡
truss [-fcaeildDE] [- [tTvx] [!] syscall ,...] [- [sS] [!] signal ,...] [- [mM] [!] fault ,...] [- [rw] [!] fd ,...] [- [uU] [!] lib ,... : [:] [!] func ,...] [-o outfile] command | -p pid[/lwps]...
truss ユーティリティーは指定されたコマンドを実行し、それ自体が実行するシステムコール、受け取ったシグナル、および検出したマシン障害の追跡情報を生成します。追跡出力の各行には、障害またはシグナルの名前、あるいはシステムコール名とその引数および戻り値が示されます。システムコールの引数は、可能なかぎの、関連するシステムヘッダー内の定義に従って記号で表示されます (パス名へのポインタ引数の場合、ポイント先の文字列が表示される)。エラーが発生した場合の戻り値は、Intro(3) のマニュアルページに説明されているエラーコード名を使用して報告されます。エラーが発生して、カーネルが失われた特権を報告する場合、特権名 (privileges(5) を参照) は、エラーコード名の後に、角括弧 ([ ]) で囲まれて報告されます。エラーレポートの詳細については、「注意事項」を参照してください。
truss は、-u オプションにより、追跡するプロセスによって実行されたユーザーレベルの関数呼び出しの開始および終了時の追跡情報も生成します。この場合、入れ子レベルを示すためにインデントが行われます。
リスト引数を受け付けるオプションでは、リスト内のすべての可能なメンバーを指定する短縮形として名前 all を使用できます。リストが ! で始まるオプションは否定を意味します (たとえば、追跡せずに除外するなど)。同じオプションを複数回指定できます。リスト内の同じ名前に対しては、あとから指定されたオプションが先に指定されているオプション (リスト内で左側にあるもの) を無効にします。
次のオプションがサポートされています。
各 exec() システムコールに渡される引数文字列を表示します。
追跡情報を 1 行ずつ表示するのではなく、追跡されたシステムコール、障害、およびシグナルをカウントします。追跡されたコマンドが終了するか、あるいは truss が割り込まれたときに、要約レポートが生成されます。-f も指定すると、子プロセスについて追跡されたシステムコール、障害、およびシグナルもすべてカウントに含められます。
追跡出力の各行にタイムスタンプを含めます。タイムスタンプは、seconds . fraction という形式で行頭に示されます。これは、追跡の開始時からの経過秒数を示したものです。追跡出力の最初の行には、個々のタイムスタンプ測定の基点となるベースタイムが、epoch からの経過秒数 (time(2) のマニュアルページを参照) と日付文字列 (ctime(3C) および date(1) のマニュアルページを参照) の両方の形式で表示されます。報告される時間は、当該イベントが発生した時間です。どのシステムコールについても、イベントはシステムコールの終了時であり、システムコールの開始時ではありません。
追跡出力の各行にデルタタイムを含めます。seconds . fraction という形式で示されるこの値は、LWP が呼び出したイベントの前回の報告以降にそのイベントが次に発生した時点までの経過時間を示します。システムコールの場合、これはシステムコール内で経過した時間ではありません。
各 exec() システムコールに渡される環境文字列を表示します。
追跡出力の各行にデルタタイムを含めます。seconds.fraction という形式で示されるこの値は、システムコールが始まってから終わるまでの経過時間を示します。
-D オプションとは異なり、この時間は、システムコール内で費やされた総時間です。
fork() または vfork() によって作成されたすべての子プロセスを追跡し、それらのシグナル、障害、およびシステムコールを追跡出力に含めます。通常は、最初のコマンドまたはプロセスだけが追跡されます。-f を指定すると、追跡出力の各行にプロセス ID が表示され、どのプロセスがシステムコールを実行したか、あるいはどのプロセスがシグナルを受信したかが示されます。
割り込み可能な休眠状態のシステムコールを表示しません。端末デバイスまたはパイプ上での open() や read() など、特定のシステムコールは不確定時間に休眠でき、割り込み可能です。一般に、システムコールが 1 秒を超えてそのような休眠状態になっている場合、truss はそれらを報告します。システムコールは完了時に再度、報告されます。-i オプションは、そのようなシステムコールを、完了時のみの 1 度だけ報告します。
追跡出力の各行に対応する軽量プロセス (LWP) の ID を含めます。-f も指定すると、プロセス ID と LWP ID の両方を含めます。
追跡または除外するマシン障害を指定します。コンマで区切ったリストに指定した障害が追跡されます。障害は、名前または番号で指定できます (<sys/fault.h> を参照)。リストが ! で始まる場合、指定された障害は追跡出力から除外されます。デフォルトは -mall -m !fltpage です。
プロセスを停止するマシン障害を指定します。指定した障害は、-m で指定されるセットに追加されます。指定された障害の 1 つが見つかると、truss はプロセスを停止したままにし、終了します (-T オプションを参照)。デフォルトは -M!all です。
追跡出力に使用されるファイル。デフォルトでは、出力は標準エラー出力に送られます。
truss に指定される command 引数を、実行されるコマンドとしてではなく、既存のプロセス (ps(1) のマニュアルページを参照) のプロセス ID のリストとして解釈します。プロセスのユーザー ID とグループ ID が実行するユーザーの ID と一致するか、あるいはユーザーが特権ユーザーである場合、truss は各プロセスを制御し、それらの追跡を開始します。ユーザーは、選択した (つまり、/thread-id をプロセス ID に追加した) スレッドだけを追跡できます。複数のスレッドを選択するには、区切り文字「-」と「,」を使用します。たとえば、「/1,2,7-9」は、スレッド 1、2、7、8、および 9 を追跡します。プロセスの指定は、/proc ディレクトリ内の名前を指定することによっても行えます (例: /proc/12345)。
指定したファイル記述子の read() ごとに、入出力バッファーの全内容を表示します。出力は行当たり 32 バイトに整形され、各バイトは ASCII 文字 (先頭に 1 個のブランクが入る)、または、水平タブ (\t) や復帰改行 (\n) などの制御文字のために 2 文字の C 言語エスケープシーケンスとして表示されます。ただし、ASCII 解釈が不可能な場合は、2 文字の 16 進表現となります (-r が指定されない場合でも追跡された各 print >read() の入出力バッファーの最初の 12 バイトは表示される)。デフォルトは -r!all です。
追跡または除外するシグナルを指定します。コンマで区切ったリストに指定したシグナルを追跡します。シグナルが無視される (ブロックされてない) 場合でも、追跡出力には、指定された各シグナルの受信が示されます (ブロックされているシグナルはブロックが解放されるまで受信されない)。シグナルは、名前または番号で指定できます (<sys/signal.h> を参照)。リストが ! で始まる場合、指定されたシグナルは追跡出力から除外されます。デフォルトは -sall です。
プロセスを停止するシグナルを指定します。指定されたシグナルは、-s で指定されるセットに追加されます。指定されたシグナルのどれかが受信された場合、truss はプロセスを停止したままにし、終了します (-T オプションを参照)。デフォルトは -S!all です。
追跡または除外するシステムコールを指定します。コンマで区切ったリストに指定されたシステムコールの追跡が行われます。リストが ! で始まる場合、指定したシステムコールが追跡出力から除外されます。デフォルトは -tall です。
プロセスを停止するシステムコールを指定します。指定されたシステムコールが、-t によって指定されるセットに追加されます。指定されたシステムコールの 1 つが見つかると、truss はプロセスを停止したままにし、終了します。つまり、truss はプロセスを解放して実行を終了しますが、当該システムコールの完了時にそのプロセスを停止状態のままにします。これにより、停止したプロセスにデバッガなどのプロセス検査ツール (proc(1) のマニュアルページを参照) を適用できるようになります。追跡を継続するには、同じオプションまたは異なるオプションを指定して、停止されたプロセスに truss を適用し直します。デフォルトは -T!all です。
この方法で停止されたままになったプロセスは、アプリケーション kill -CONT によって再開することはできません。これは、停止シグナル (signal.h(3HEAD) のマニュアルページを参照) のデフォルトアクションによってではなく、/proc を介したイベント上でこのプロセスが停止されているためです。停止中のプロセスを再実行するように設定するには、proc(1) のマニュアルページで説明されている prun(1) コマンドを使用できます。
ユーザーレベルの関数呼び出しを追跡します。lib, . . . は、動的なライブラリ名 (.so.n 接尾辞を除く) をコンマで区切ったリストです。func, . . . は、関数名をコンマで区切ったリストです。どちらの場合でも、名前の表現にメタ文字 *、?、[] を使用できます。これらのメタ文字の指定は sh(1) における指定と同じ意味を持ちますが、ファイルに対してではなくライブラリ名または関数名に対して使用されることになります。ライブラリまたは関数のリストを空にすると、デフォルトで * が使用され、ライブラリ内のすべてのライブラリまたは関数が追跡されます。リストの先頭に ! を付けると、追跡から除外されるライブラリまたは関数の名前を指定したことになります。1 つのライブラリを除外すると、そのライブラリ内のすべての関数が除外されます。つまり、ライブラリ除外リストのあとに続く関数リストは無視されます。
関数リストとライブラリリストを分離する 1 つの : は、ライブラリの外部から、それらのライブラリに対する呼び出しは追跡しますが、ライブラリ内部の他の関数からの呼び出しは除外することを意味します。2 つの : : は、呼び出し元に関係なくすべての呼び出しを追跡することを意味します。
ライブラリのパターンには、正確な一致がないかぎり、実行可能ファイルと動的リンカーのいずれとも対応付けはしません (l* は ld.so.1 に対応付けられない)。これらのオブジェクトのどちらかに含まれる関数を追跡するには、次のように名前を明確に指定する必要があります。
truss -u a.out -u ld ...
a.out はこの目的で使用されるリテラル名であり、実行可能ファイルの名前を意味するわけではありません。a.out 関数呼び出しを追跡すると、すべての呼び出しが暗黙に追跡されます (デフォルトは : :)。
-u オプションは複数回指定することが可能で、この場合左から順に受け付けられます。プロセスが lthread にリンクしている場合は、呼び出しの追跡出力に関数呼び出しを行なったスレッドの ID が含められます。truss は、関数名を見つけるために各ライブラリ内の動的シンボルテーブルを検索するとともに、ストリップされてなければ標準のシンボルテーブルも検索します。
プロセスを停止するユーザーレベルの関数呼び出しを指定します。指定される関数は、-u で指定されるセットに追加されます。指定された関数の 1 つが呼び出されると、truss はプロセスを停止したままにし、終了します (-T オプションを参照)。
冗長。指定されたシステムコールに対してアドレスで渡された任意の構造体の内容を表示します (-t による追跡が行われた場合)。入力した値とオペレーティングシステムによって返される値が示されます。入力と出力の両方に使用されるフィールドについては、出力値だけが示されます。デフォルトは -v!all です。
指定したファイル記述子の write() ごとに入出力バッファの内容を表示します (-r オプションを参照)。デフォルトは -w!all です。
指定されたシステムコールの引数を raw 形式で表示します (-t による追跡が行われた場合)。これは、通常、記号表示ではなく 16 進表示であり、raw ビットのままの方が良いと考えるハッカーのためのものです。デフォルトは -x!all です。
-t、-T、-v、および -x オプションが受け付けるシステムコール名については、『『man pages section 2: System Calls』』を参照してください。システムコール番号も指定できます。
指定したコマンドを開始および追跡するのに truss を使用する場合、-o オプションを使用するか、あるいは標準エラー出力を端末以外のファイルにリダイレクトすると、truss はハングアップ、割り込みシグナル、および終了シグナルを無視して動作します。これにより、端末からの割り込みシグナルと終了シグナルを受け取る対話型プログラムの追跡が容易になります。
追跡出力を端末に転送したままにした場合、あるいは、既存のプロセスを追跡する (-p オプション) 場合、truss は追跡したすべてのプロセスを解放して処理を終了するので、ハングアップ、割り込み、終了の各シグナルに応答します。これにより、ユーザーは過度の追跡出力を抑制でき、既存のプロセスを解放できるようになります。解放されたプロセスは、なんの影響も受けず、それまでどおりの通常の処理を継続します。
既存のプロセスを追跡すると、truss はプロセスを解放して、truss 終了時に実行中に設定します。これには、SIGINT、SIGHUP、SIGQUIT などのシグナルによる終了も含まれます。これにより、ユーザーは過度の追跡出力を抑制でき、既存のプロセスを解放できるようになります。解放されたプロセスは、なんの影響も受けず、それまでどおりの通常の処理を継続します。
例 1 コマンドを追跡する
この例は、端末上の find(1) コマンドの追跡情報を生成します。
example$ truss find . -print >find.out
例 2 一般的なシステムコールを追跡する
オープン、クローズ、読み取り、書き込みの各システムコールの追跡情報だけを表示するには、次のように指定します。
example$ truss -t open,close,read,write find . -print >find.out
例 3 シェルスクリプトを追跡する
この例は、ファイル truss.out 上の spell(1) コマンドの追跡情報を生成します。
example$ truss -f -o truss.out spell document
spell はシェルスクリプトであるため、シェルだけでなくシェルによって生成されたプロセスも追跡するためには -f フラグが必要です (spell スクリプトは 8 つのプロセスのパイプラインを実行する)。
例 4 出力を簡潔にする
出力を簡潔にする例を示します。
example$ truss nroff -mm document >nroff.out
この例は、出力の 97% が lseek()、read()、および write() システムコールの追跡情報であり、冗長です。出力を簡潔にまとめるには次のように指定します。
example$ truss -t !lseek,read,write nroff -mm document >nroff.out
例 5 C ライブラリの外部からのライブラリ呼び出しを追跡する
この例は、C ライブラリの外部から C ライブラリ内の任意の関数に対して行われるユーザーレベルの呼び出しをすべて追跡します。
example$ truss -u libc ...
例 6 C ライブラリ内からのライブラリ呼び出しを追跡する
この例では、C ライブラリからその C ライブラリ自体の関数に対して行われる呼び出しが含められます。
example$ truss -u libc:: ...
例 7 C ライブラリ以外のライブラリ呼び出しを追跡する
この例は、C ライブラリ以外のすべてのライブラリに対して行われるユーザーレベルの呼び出しをすべて追跡します。
example$ truss -u '*' -u !libc ...
例 8 pritf および scanf 関数呼び出しを追跡する
この例は、C ライブラリに含まれる printf および scanf ファミリ内の関数に対するユーザーレベルの呼び出しをすべて追跡します。
example$ truss -u 'libc:*printf,*scanf' ...
例 9 ユーザーレベルの関数呼び出しをすべて追跡する
この例は、任意の場所から任意の場所に対して行われるユーザーレベルの関数呼び出しをすべて追跡します。
example$ truss -u a.out -u ld:: -u :: ...
例 10 システムコールの追跡結果を詳細に表示する
この例は、プロセス #1 の init(1M) システムコールのアクティビティーを追跡し、詳細な追跡情報を表示します (特権ユーザーがこのコマンドを実行できます)。
example# truss -p -v all 1
truss に割り込みを行うと、init は通常の動作に戻ります。
プロセスファイル
属性についての詳細は、マニュアルページの attributes(5) を参照してください。
|
date(1), find(1), proc(1), ps(1), sh(1), spell(1), init(1M), Intro(3), exec(2), fork(2), lseek(2), open(2), read(2), time(2), vfork(2), write(2), ctime(3C), signal.h(3HEAD), proc(4), attributes(5), mwac(5), privileges(5), threads(5)
『man pages section 2: System Calls』
『『man pages section 2: System Calls』』で説明されているシステムコールの中には、実際のオペレーティングシステムインタフェースとは異なるものがあります。追跡情報が、この説明と若干異なる場合もあります。
マシン障害 (ページフォルトは除く) が発生するたびに、障害の原因となった LWP にシグナルが送られます。シグナルがブロックされない場合、各マシン障害 (ページフォルトを除く) が通知された直後に、受信シグナルが通知されます。
オペレーティングシステムは、プロセスの追跡に一定のセキュリティ制限を課します。具体的には、ユーザーは、自身が読み取りできないオブジェクトファイル (a.out) を持つコマンドを追跡することはできません。set-uid と set-gid をもつコマンドは、特権ユーザー以外は追跡できません。特権ユーザーが実行する場合を除き、truss は set-id または読み取り不可能なオブジェクトファイルの exec() を実行するプロセスを制御できません。このようなプロセスは、truss からは独立して、exec() ポイントで通常どおり処理を継続します。
ほかの制御プロセスとの衝突を防ぐため、truss は、/proc インタフェースを介してほかのプロセスによって制御されているプロセスを追跡しません。このため、truss を proc(4) ベースのデバッガだけでなく、それ自身の別のインスタンスにも適用できます。
8 カラムごとに標準のタブストップが設定されていると仮定して、追跡出力にはタブ文字が含まれます。
複数のプロセスまたはマルチスレッドプロセス (複数の LWP) を含むプロセス) の追跡出力は、厳密に時間順には生成されません。たとえば、パイプにおける read() は、対応する write() よりも前に報告される場合があります。しかし、個々の LWP (従来型のプロセスには 1 つしか含まれない) について出力は、厳密に時間順に行なわれます。
複数のプロセスを追跡する場合、truss は追跡対象のプロセスごとに 1 つの制御プロセスとして動作します。前述の spell コマンドの例の場合、spell 自身が 9 つのプロセススロット (シェル用に 1 つ、8 メンバーを持つパイプライン用に 8 つ) を使用し、truss がさらに 9 つのプロセスを追加するため、プロセススロットは合計で 18 になります。
-v オプションでは、すべてのシステムコールで渡すことができるあらゆる構造体を表示できるわけではありません。
truss は、失われた特権が原因で発生したシステムコールによって返されたエラーをレポートする場合、エラーコードと単純な特権名を続けて表示するか、または特権の詳細な説明を表示します。privileges(5) を参照してください。詳細な説明には、以下の内容を含めることができます。
このプロセスでは、要求された操作のための特権がすべて必要になります。
このプロセスには、複数の特権はありません。
このプロセスでは、ゾーン (ALL のゾーンローカルバリアント) で使用できる特権の 1 つがありません。
要求された操作では、プロセスがグローバルゾーンで実行されている必要があります。
要求された操作は、プロセス用に定められている mwac(5) ポリシーに違反しています。