straceを使用してLinuxシステムコールを監視する方法

公開: 2022-01-29
ラップトップPCの定型化されたターミナルウィンドウ。
fatmawati achmad zaenuri / Shutterstock.com

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を知っている必要があります。 これを見つけるためにgreppsを使用できます。 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ラップトップ