strace コマンド
strace コマンドを使用すると、行われたシステム コールと、プロセスによって受信されたシグナルを傍受して記録できます。これにより、ユーザー空間とカーネル空間の間の境界層を調べることができ、プロセスが失敗した理由を特定するのに非常に役立ちます。
strace を使用して、プログラムがシステムと対話する方法を分析することは、ソース コードがすぐに利用できない場合に特に役立ちます。
トラブルシューティングにおけるその重要性に加えて、strace はシステムの動作方法に関する深い洞察を提供できます。すべてのユーザーは、自分の実行中のプロセスを追跡できます。さらに、root ユーザーは実行中のプロセスを追跡できます。たとえば、次のコマンドを使用して、実行中の rsyslogd デーモンにアタッチしてトレースできます:
# strace -p $(pgrep rsyslogd) Process 819 attached select(1, NULL, NULL, NULL, {83009, 275934} ...
strace 出力
strace からの出力は、システム コールまたはシグナルのいずれかに対応します。システム コールからの出力は、次の 3 つのコンポーネントで構成されます。
1.システムコール
2.括弧で囲まれた任意の引数
3.等号に続く呼び出しの結果
-1 の終了ステータスは通常、エラーを示します。例:
# strace ls file1 execve("/bin/ls", ["ls", "file1"], [/* 21 vars */]) = 0 brk(0) = 0xadb000 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f516bb79000 ..... close(1) = 0 munmap(0x7f516bb78000, 4096) = 0 close(2) = 0 exit_group(0) = ? +++ exited with 0 +++
中括弧は、参照解除された C 構造体を示すために使用されます。角括弧は、単純なポインターまたは値の配列を示すために使用されます。
strace コマンドの例
ファイルへのトレースのリダイレクト
strace は大量の出力を作成することが多いため、出力をファイルにリダイレクトすると便利なことがよくあります。たとえば、次のコマンドを使用して、bash シェルを起動し、フォークされた子プロセスをトレースし、files.trace ファイルへのすべてのファイル アクセスを記録できます:
# strace -f -o files.trace -e trace=file bash
sys コールのカウント数
ls コマンドを実行して、各システム コールが行われた回数をカウントし、各コールに費やされた回数と時間を示す合計を出力します (基本的なプロファイリングやボトルネックの分離に役立ちます):
# strace -c ls
プロセス/デーモンによって開かれたファイルの表示
次の例は、OpenSSH の sshd が起動時に読み取る 3 つの構成ファイルを示しています。 strace はデフォルトで出力を STDERR に送信することに注意してください。したがって、さらに変更するために grep などの他のコマンドにパイプする場合は、出力を適切にリダイレクトする必要があります。
# strace -f -eopen /usr/sbin/sshd 2>&1 | grep ssh
ネットワーク関連のシステム コールのみをトレースする
Netcat がローカル telnetd サービスへの接続を試みるときに、ネットワーク関連のシステム コールだけをトレースします。
# strace -e trace=network nc localhost 23
ltrace コマンド
ltrace コマンドを使用すると、共有ライブラリに対して行われた動的呼び出しをインターセプトして記録できます。一部のコマンドでは、ltrace コマンドによって生成される出力の量が膨大になることがあります (特に、システム コールを表示するために -S オプションが使用されている場合)。プログラムとライブラリのリストとの間の相互作用だけに出力を集中させることができます。たとえば、id -Z コマンドを実行して、libselinux.so モジュールに対して行われた呼び出しを表示するには、次のように実行します。
$ ltrace -l /lib/libselinux.so.1 id -Z is_selinux_enabled(0xc1c7a0, 0x9f291e8, 0xc1affc, 0, -1)a =1 getcon(0x804c2c8, 0xfee80ff4, 0x804b179, 0x804c020, 0)a =0 user_u:system_r:unconfined_t
ldd コマンドを使用して、プログラムがリンクされているライブラリを確認できることを忘れないでください。