straceを使用してLinuxシステムコールを監視する方法
公開: 2022-01-29 Linuxプログラムは、カーネルにいくつかのことを実行するように要求します。 strace
コマンドは、これらのシステムコールを明らかにします。 それらを使用して、プログラムがどのように機能するのか、そしてなぜ機能しないのかを理解することができます。
カーネルとシステムコール
彼らがそうであるかもしれないのと同じくらい賢いので、コンピュータプログラムは彼ら自身のためにすべてをすることができません。 彼らは彼らのために特定の機能を実行させるために要求をする必要があります。 これらのリクエストはLinuxカーネルに送られます。 通常、プログラムが呼び出すライブラリまたはその他のソフトウェアインターフェイスがあり、ライブラリはカーネルに対して適切な要求(システムコールと呼ばれる)を行います。
プログラムが行ったシステムコールとその応答を確認できると、興味のあるプログラムや作成したプログラムの内部動作を理解するのに役立ちます。 これはstrace
が行うことです。 問題のトラブルシューティングとボトルネックの検索に役立ちます。
これは、 gdb
などのツールを使用してアプリケーションをデバッグすることと同じではありません。 デバッグプログラムを使用すると、実行中のプログラムの内部動作を調査できます。 プログラムのロジックをステップスルーし、メモリと変数の値を検査できます。 比較すると、 strace
が行うことは、プログラムの実行中にシステムコール情報をキャプチャすることです。 トレースされたプログラムが終了すると、 strace
はシステムコール情報をターミナルウィンドウに一覧表示します。
システムコールは、ファイルに対する読み取りおよび書き込みアクション、プロセスの強制終了など、あらゆる種類の低レベル機能を提供します。 syscallsのマニュアルページには、何百ものシステムコールのリストがあります。
関連: GDBを使用したデバッグ:はじめに
straceのインストール
strace
コンピューターにインストールされていない場合は、非常に簡単にインストールできます。
Ubuntuでは、次のコマンドを使用します。
sudo apt install strace
Fedoraでは、次のコマンドを入力します。
sudo dnf install strace
Manjaroでは、コマンドは次のとおりです。
sudo pacman -Sy strace
straceを使用した最初のステップ
小さなプログラムを使用してstrace
をデモンストレーションします。 あまり効果はありません。ファイルを開いて1行のテキストを書き込み、エラーチェックを行いません。 strace
で使用できるものがあるように、これは簡単なハックです。
#include <stdio.h> int main(int argc、char argv []){ //ファイルハンドル FILE * fileGeek; //「strace_demo.txt」というファイルを開くか、作成します fileGeek = fopen( "strace_demo.txt"、 "w"); //ファイルにテキストを書き込みます fprintf(fileGeek、 "これをファイルに書き込む"); //ファイルを閉じます fclose(fileGeek); //プログラムを終了します 戻り値(0); } //メインの終わり
これを「file- io.c 」というファイルに保存し、 gcc
を使用して「 straceexample 」という名前のstex
という実行可能ファイルにコンパイルしました。
gcc -o stexfile-io.c
コマンドラインからstrace
を呼び出し、トレースしたいプロセスとして新しい実行可能ファイルの名前を渡します。 Linuxコマンドやその他のバイナリ実行可能ファイルを簡単に追跡できます。 私たちは2つの理由で小さなプログラムを使用しています。
最初の理由は、 strace
が冗長であるということです。 多くの出力が存在する可能性があります。 怒りの中でstrace
を使用している場合、これは素晴らしいことですが、最初は圧倒される可能性があります。 私たちの小さなプログラムのstrace
出力は限られています。 2つ目の理由は、プログラムの機能が制限されており、ソースコードが短くてわかりやすいことです。 これにより、出力のどのセクションがプログラムの内部動作のさまざまな部分を参照しているかを簡単に識別できます。
strace ./stex
「これをファイルに書き込む」というテキストを開いたファイルに送信するwrite
システムコールとexit_group
システムコールをはっきりと見ることができます。 これにより、アプリケーション内のすべてのスレッドが終了し、戻り値がシェルに返されます。
出力のフィルタリング
簡単なデモンストレーションプログラムでも、かなりの量の出力があります。 -e
(式)オプションを使用できます。 表示したいシステムコールの名前を渡します。
strace -e write ./stex
複数のシステムコールをコンマ区切りのリストとして追加することで、それらについてレポートできます。 システムコールのリストに空白を含めないでください。
strace -e close、write ./stex
出力をファイルに送信する
出力をフィルタリングすることの利点は、出力をフィルタリングする際の問題でもあります。 要求したものは表示されますが、他には何も表示されません。 そして、他の出力のいくつかは、あなたが見たいと思ったものよりもあなたにとってもっと役立つかもしれません。
場合によっては、すべてをキャプチャして、結果のセット全体を検索およびスクロールする方が便利な場合があります。 そうすれば、重要なものを誤って除外することはありません。 -o
(出力)オプションを使用すると、 strace
セッションからの出力をテキストファイルに送信できます。
strace -o trace-output.txt ./stex
次に、 less
コマンドを使用して、リストをスクロールし、システムコール(またはその他)を名前で検索できます。
少ないtrace-output.txt
これで、 less
のすべての検索機能を使用して出力を調査できます。
関連: Linuxでlessコマンドを使用する方法
タイムスタンプの追加
出力にいくつかの異なるタイムスタンプを追加できます。 -r
(相対タイムスタンプ)オプションは、連続する各システムコールの開始間の時間差を示すタイムスタンプを追加します。 これらの時間値には、前のシステムコールで費やされた時間と、次のシステムコールの前にプログラムが実行していたその他の時間が含まれることに注意してください。
strace -r ./stex
タイムスタンプは、出力の各行の先頭に表示されます。
各システムコールに費やされた時間を確認するには、 -T
(syscall-times)オプションを使用します。 これは、各システムコール内で費やされた時間を示します。
strace -T ./stex
期間は、各システムコールラインの最後に表示されます。
各システムコールが呼び出された時刻を確認するには、 -tt
(絶対タイムスタンプ)オプションを使用します。 これは、マイクロ秒の分解能で「実時間」を示しています。
strace -tt ./stex
時間は各行の先頭に表示されます。
実行中のプロセスのトレース
トレースするプロセスがすでに実行されている場合でも、 strace
をアタッチできます。 そのためには、プロセスIDを知っている必要があります。 これを見つけるためにgrep
でps
を使用できます。 Firefoxを実行しています。 firefox
プロセスのIDを見つけるために、 ps
を使用してgrep
にパイプすることができます。
ps -e | grep firefox
プロセスIDが8483であることがわかります。 -p
(プロセスID)オプションを使用して、どのプロセスに接続するかをstrace
に指示します。 sudo
を使用する必要があることに注意してください:
sudo strace -p 8483
strace
がプロセスにアタッチされたという通知が表示され、システムトレース呼び出しが通常どおりターミナルウィンドウに表示されます。
レポートの作成
-c
(要約のみ)オプションを指定すると、 strace
はレポートを出力します。 トレースされたプログラムによって行われたシステムコールに関する情報のテーブルを生成します。
strace -c ./stex
列は次のとおりです。
- %時間:各システムコールに費やされた実行時間のパーセンテージ。
- 秒:各システムコールに費やされた秒とマイクロ秒で表される合計時間。
- usecs / call :各システムコールに費やされたマイクロ秒単位の平均時間。
- 呼び出し:各システムコールが実行された回数。
- エラー:各システムコールの失敗の数。
- syscall :システムコールの名前。
これらの値は、実行および終了が迅速な些細なプログラムの場合はゼロを示します。 デモンストレーションアプリケーションよりも意味のあることを行うプログラムの実際の値が表示されます。
ディープインサイト、簡単に
strace
出力は、どのシステムコールが行われているのか、どのシステムコールが繰り返し行われているのか、カーネル側のコード内でどのくらいの実行時間が費やされているのかを示します。 それは素晴らしい情報です。 多くの場合、コード内で何が起こっているのかを理解しようとすると、バイナリがカーネルとほぼノンストップで相互作用してその機能の多くを実行していることを忘れがちです。
strace
を使用すると、全体像を確認できます。
Linuxコマンド | ||
ファイル | tar・pv・cat・tac・chmod・grep・diff・sed・ar・man・pushd・popd・fsck・testdisk・seq・fd・pandoc・cd・$ PATH・awk・join・jq・fold・uniq・journalctl・tail・stat・ls・fstab・echo・less・chgrp・chown・rev・look・strings・type・rename・zip・unzip・mount・umount・install・fdisk・mkfs・rm・rmdir・rsync・df・gpg・vi・nano・mkdir・du・ln・patch・convert・rclone・shred・srm | |
プロセス | エイリアス・screen・top・nice・renice・progress・strace・systemd・tmux・chsh・history・at・batch・free・which・dmesg・chfn・usermod・ps・chroot・xargs・tty・pinky・lsof・vmstat・タイムアウト・wall・yes・kill・sleep・sudo・su・time・groupadd・usermod・groups・lshw・shutdown・reboot・halt・poweroff・passwd・lscpu・crontab・date・bg・fg | |
ネットワーキング | netstat・ping・traceroute・ip・ss・whois・fail2ban・bmon・dig・finger・nmap・ftp・curl・wget・who・whoami・w・iptables・ssh-keygen・ufw |
関連:開発者と愛好家のための最高のLinuxラップトップ