...

strace を使ったシステムコールの分析:エラーの原因を迅速に特定する

と一緒に strace Linux ライブで、どれが システムコール straceを実際に活用することで、ボトルネックや権限の問題、欠落しているファイルをはるかに迅速に見つけられるようになりました。謎めいたログとは異なり、straceは問題の発生箇所で、最初に失敗した呼び出し、引数、エラーコードを明確に表示してくれます。まさにこの機能のおかげで、トラブルシューティングの時間が大幅に短縮されています。.

中心点

以下の重要なポイントを押さえることで、strace を使ってエラーの原因をより迅速に特定し、正確に絞り込むことができます。.

  • 透明性: システムコールを直接確認することで、原因が明らかになる。.
  • フィルター: ファイル、プロセス、またはネットワークのみをターゲットに追跡する。.
  • リアルタイム分析: 実行中のPIDを追跡し、ボトルネックを特定する。.
  • 比較: 異なるホストとビルドを比較する。.
  • 概要: 頻繁に行われる高額な呼び出しをまとめて確認する。.

システムコールの概要

をセットした。 ストレース アプリケーションがフリーズしたり、不自然に動作が遅くなったり、理由もなく停止したりした場合は、出力結果から即座に実際の 手続き ユーザー空間とカーネルの間にあることを示しています。 各行には関数名、パラメータ、戻り値、errno、シグナルが含まれているため、どこで問題が発生しているかを即座に把握できます。多くの場合、最初のエラーメッセージが問題の真の起点を示しています。例えば、期待していたファイルに対してopenatを実行した際にENOENTが発生した場合などです。 プロセスが停止した場合、繰り返し行われるfutexやポーリングの呼び出しを待機パターンと解釈します。私にとっては、これがログに取って代わるものではありませんが、システム境界のすぐそばにおける決定的な詳細情報を補完してくれるものです。.

はじめに:strace を使ってプロセスを直接実行する

新しい実行結果を調査したいときは、直接次のようにプログラムを起動します。 ストレース, 、例えば strace ls といったコマンドを使って、その完全な シーケンス 呼び出されたシステム関数についてです。-e trace=file を指定するとファイルアクセスに焦点を当てることができ、-e trace=process を指定すると fork、execve、exit が表示されます。ネットワーク関連の場合は -e trace=network に焦点を当てることで、connect、sendto、recvfrom がすぐに目につくようになります。 表示された行の量だけでは構造が把握しづらい場合は、-c オプションを使用すると、頻度と時間の統計情報がコンパクトにまとめられます。これにより、どのコールが実行時間を占めているか、どこにボトルネックが発生しているかを瞬時に把握できます。.

実行中のサービスを追加してフォーカスする

すでに稼働中のサービスについては、私は以下を使用しています strace -p PID そして、その対象の インスタンス, 、再起動のリスクやダウンタイムを伴わずに実行できます。-f オプションを使用すると子プロセスも対象に含めることができ、これはWebサーバーやワーカーなどにおいて不可欠です。-tt によるタイムスタンプや -T による所要時間の表示は、依存関係や待機時間を時間軸に沿って正確に把握するのに役立ちます。 ファイルアクセスだけを確認したい場合は、-e trace=file オプションで出力を制限し、システムへの負荷を低く抑えます。カーネルの遷移に関する簡潔な予備知識が必要な方は、こちらの簡単な入門記事をご覧ください: システムコールの理解, 、これによりstraceの出力行を読みやすくなります。.

エラーメッセージを素早く読み解く:ファイル、権限、フリーズ

典型的なパターンは、ほんの少しの兆候から見分けられる ヒント: ENOENTはパスが見つからないことを示しており、EACCESやEPERMは 認可, 一方、futexの呼び出しが継続している場合や、ppoll/pselectがロックや待機状態を示している場合は、ポートや相手先を確認します。EADDRINUSEやECONNREFUSEDが発生した場合は、ポートや相手先を確認します。 TLSやDNSの問題が発生した場合は、connect/recvfromの処理履歴や行間の時間差を評価します。 同じファイルに対する openat の呼び出しが繰り返し失敗する場合は、たいてい検索パスが間違っているか、環境変数が破損していることが原因です。そのため、最初の重大なエラーを特定するのにそれほど時間はかかりません。.

時間とコストの構造を可視化する

-c オプションを指定すると、簡潔な統計情報が表示され、そこから 株式 およびシステム機能ごとの呼び出し頻度を示しており、これにより、 チューニング と気づきました。-tt と -T を追加すれば、正確なタイムスタンプと各コールの所要時間を記録できます。これは、時折発生するフリーズの調査において非常に役立ちます。 2行の間に長い間隔がある場合は、I/Oやネットワークの休止が疑われます。小さな読み取りアクセスが多数見られる場合は、アプリケーションのバッファリングやファイルシステムへのアクセスを確認します。これにより、手探り状態になることなく、的を絞って最適化を進めることができます。.

ホストとビルドの比較

ある処理がホストAでは正常に実行されるものの、ホストBでは失敗する場合、私は両方の実行を次のように開始します。 ストレース そして、これを比較して 相違点 パス、errno、ライブラリ、環境変数について。これにより、パッケージが欠落しているか、別の検索パスが有効になっているか、あるいは権限が異なるかを素早く確認できます。 openat や statx といったシステムコールの順序やターゲットパスに差異が見られる場合、それはたいてい起動コンテキストが異なることを示しています。より詳細なパフォーマンスに関する問題については、追加でツールを組み込んでいます。この概要については ホスティングにおけるbpftrace これにより、カーネルのイベントをさらに正確に把握できるようになります。straceとbpftraceを組み合わせて使用することで、リクエストがシステム内をどのように通過するかの明確な全体像が得られます。.

ログは補完するものであり、置き換えるものではない

読み続けます アプリケーションログ, 、しかし、メッセージが不可解だったり、まったく表示されなかったりする場合には、straceがコードとカーネルの間のギャップを埋めてくれるため、 検索 原因を特定することで、対応時間を大幅に短縮できます。セキュリティ関連の課題については、私は分析と監査活動を組み合わせることを好んでいます。セキュリティインシデントを体系的に記録している方は、このガイドを活用すると良いでしょう: auditd のログを正しく記録する. これにより、例えばポリシーによってアクセスがブロックされているかどうかを確認できる一方で、straceは対応するerrnoを表示してくれます。この2つの視点から、より全体像を把握することができます。重要なのは、出力が膨大になりすぎないように、straceの実行時間を短く抑えることです。.

迅速な絞り込みのための診療ワークフロー

まず、 質問 処理に関して:フリーズ、クラッシュ、誤った結果、または応答が遅いといった問題が発生した場合、正しい オプション 選択します。再起動する場合は、-e trace=file や -e trace=network といったフィルタを指定して strace を使用し、そうでない場合は -p オプションでサービスに接続します。その後、エラーが発生するまで監視し、セッションを終了します。 問題の行については、直ちに修正を行います。パスの確認、権限の調整、エンドポイントのテストを行います。原因が特定できない場合は、時間情報を拡張し、-cオプションを使用してホットスポットを特定します。.

出力を記録し、後で分析する

エラーがめったに発生しない場合は、出力を次のようにリダイレクトします。 -o ファイルに書き出し、-ff オプションで以下の区分を設定します PID 。このようにして、親プロセスと子プロセスの活動を別々に記録しています。-s オプションを指定すると、引数の出力長を延長できます。これは、パスが切り詰められて重要な情報が得られなくなる場合に対応するためです。 実行時間が長くなる場合は、データ量を管理可能な範囲に抑えるため、例えば次のエラー発生地点までといった明確な停止条件を設定します。その後、grep を使ってファイルを errno や呼び出しタイプでフィルタリングすることで、関連する行を瞬時に抽出します。.

straceの重要なオプションの概要

以下の表は、最も一般的なものをまとめたものです。 オプション そしてその実用的な ベネフィット まとめておけば、慌ただしいエラー分析の際に長時間探す必要がなくなります。.

オプション 目的 代表的な使用例
-e trace=file ファイル操作に焦点を当てる open/openat、statx、access を素早く確認する
-e trace=process プロセス活動を表示する fork/execve/clone および exit の追跡
-e trace=network ネットワーク呼び出しのフィルタリング connect、sendto、recvfrom を分離する
-p PID 進行中のプロセスに追加する 再起動不要のサービスを調査する
-f 子プロセスを含める ワーカーとスポーンを完全に把握する
-c 統計の概要 通話ごとの頻度と所要時間
-tt / -T より詳細な時刻 時間軸と期間を把握する
-o ファイル 出力のリダイレクト 後日の分析を可能にする
-ff プロセスファイルごとに書き込み 親と子を分ける
-s N 引数の長さを増やす 切り取られたパスを表示する

安全性、権利、および副作用

私はいつもその オーバーヘッド straceはすべての呼び出しをインターセプトして記録するため、時間的な 効果 を引き起こす可能性があります。そのため、リソースが限られた本番環境では、的を絞って短時間でトレースを行います。システムによっては、ptrace_scope や SELinux ポリシーといった、アクセスを制限するセキュリティメカニズムが適用される場合があるため、事前に確認を行います。 機密データを扱うプロセスを分析する場合は、出力内容を編集するか、隔離された環境で分析を行います。これにより、機密性を確保しつつ、負荷を適度に抑え、かつ迅速な結果を得ることができます。.

日常生活での実践例

Webサービスが起動するものの、500エラーを返す場合: -e trace=file 足りないものをすぐに見つけられる コンフィグ-File:openatがENOENTを返すため。CLIツールは即座に終了する:ライブラリでEACCESが発生しているのを確認し、権限を適切に設定する。アプリケーションの動作が遅い:-cオプションで多数の小さなread呼び出しが確認されたため、バッファリングを増やし、システムコールの洪水を軽減する。 ワーカーがハングアップしている:futexが永続的に保持されているため、コード内のロックを確認し、ブロックを解除する。DNSタイムアウトが確認される:sendtoとrecvfromの間に間隔があることから、アプリ外のネットワーク問題であることがわかる。.

データの内容と記述子のコンテキストを可視化する

単なる戻り値だけでは不十分な場合は、必要に応じて非表示にします データバッファ およびその文脈について ファイル記述子 。で -s N 引数の表示文字数を増やして(例:256文字または1024文字)、完全なパス、JSONブロック、またはヘッダーを確認できるようにします。非表示のコンテンツについては、 -x (非ASCII文字を16進数で)または -xx (すべて16進数表記)で、これは特にバイナリプロトコルで役立ちます。 -e read=all そして -e write=all read()/write() の呼び出しによる実際の有効データを表示させ、リクエストやレスポンスが妥当かどうかを確認します。並行して、私はよく -y, 、これによりstraceがファイル記述子に対応するパスも出力するようにする(例:3)、そして -yy Socketsに関する詳細についてはこちらをご覧ください。このネストの深さは、すぐに大量の出力を生成し、機密データを含む可能性があるため、控えめに使用しています。そのため、本番環境では 深いネックライン そして、ファイルを定期的にローテーションしてください。.

より詳細なフィルタ:システムコール、パス、除外条件

集中力を維持するために、あらかじめ用意されたカテゴリに加えて、次のようなものも活用しています。 微細なフィルター. 私は~で制限する -e trace=openat,statx,access 今まさに興味があるシステム呼び出しを正確に指定するか、あるいは引き続き次のようなカテゴリにアクセスするか -e trace=signal 或いは -e trace=ipc シグナルやプロセス間通信に注目したいときは、ここに戻ります。また、実用的な点として -P PATH, 1つまたは複数の 具体的な道筋 例えば、-P /etc,/var/www といったものが表示されます。もし、次のような長期間にわたって稼働しているプロセスが futex 気になる場合は、フィルタの仕組みを逆にして、関連する呼び出しだけを明示的に指定することで、それを除外します。そうすることで、 ラウシャーム エラーの発生箇所を特定しつつ、オーバーヘッドを最小限に抑える。.

タイムライン、スタックトレース、および短時間の実行を確実に記録する

「時代」こそが私の羅針盤だ。そのほかには -tt 正確なタイムスタンプをつける際には、私はよく -ttt, 、複数のホストにわたる実行結果を比較したい場合、エポックタイムスタンプがあると分析が簡単になるからです。. -r 起動からの相対的な距離を表示してくれるので、 休憩コーナー 一目で把握できるようになります。たまにクラッシュしたときは、これが役に立ちます -i (命令ポインタ) と合わせて -k (スタックトレース)を使用して、コストのかかる呼び出しやエラーが発生した呼び出しがどのスタックコンテキストから発生しているかを確認します。デバッグ情報が利用可能な場合に特に役立ちます。非常に 短命な プログラムやcronジョブは、straceの下で直接実行するか、あるいは -ff -o, 、これにより、初期のexecveや初期化処理を見逃さないようにするためです。複数の実行結果を比較したい場合は、-c統計情報を次のようにソートします。 -S time, 、総所要時間における急激な変動をより早く検出するために。.

スレッド、フォーク、複雑なサービスツリーを確実に把握する

すぐに 複数のプロセスまたはスレッド が関与している場合、私は -f を指定して子プロセスを実行させ、さらに -ff PIDごとに別々の出力ファイルを作成します。これにより、後で各ワーカーについて個別のスレッドを分析でき、混同を防ぐことができます。また、短命な子プロセスが多数存在する環境では、以下の組み合わせが役立ちます。 -e trace=process (execve/clone/fork/exit) および 時刻, 、時間の経過に伴うプロセスの生成と終了を理解するために。「親が子を待機している」といった繰り返し現れるパターンは、 wait4 さらに、子どもに活動が見られない場合は、ブロックやリソース不足を示唆しています。移行作業を支援する際、私は旧ホストと新ホストのサービスツリーを比較し、それによって ワーカーの分散 或いは プレフォーキング まったく同じように進行するか、あるいは気づかれないうちに逸脱するか。.

日常におけるコンテナ、ネームスペース、および権限

コンテナや 名前空間-シナリオでは、事前に権限を計画しています。外部プロセスに追跡を行うには、適切な権限や機能(CAP_SYS_PTRACEなど)が必要であり、また次のようなセキュリティメカニズムも必要です。 ptrace_scope あるいは、ポリシーによってアクセスがブロックされる場合があります。ターゲットとトレーサーが さまざまな名前空間, 同じネームスペースに追加するか、意図的にターゲットコンテキストに切り替えます。また、オーケストレーションされた環境では、PIDの有効期間が短いことも考慮し、 トレースを回転させる そうしなければ、関連する期間のデータが失われてしまうからです。機密データが通信回線を通過する際は、送信するコンテンツを最小限に抑え(例:ペイロードの全文を送信しないなど)、実行時間を厳密に 問題の発生段階, 、副作用を最小限に抑えるために。.

ビルドおよびリリース・パイプラインにおけるStrace

私もstraceを使っています 早い CI/CDにおいて、パッケージ化、パス、および権限を検証するため。以下のコマンドによるドライラン: -e trace=file ビルドコンテナから生成されたバイナリが、後でターゲットシステム上で同じライブラリや設定パスを見つけられるかどうかを素早く確認できます。回帰テストを行う際には、私は ベースライン: -c オプションと一貫したオプション(例:-ttt、-S time)を指定して短時間実行した結果を、基準値として用います。後のパイプライン処理では、統計値を比較して、 statx, read 或いは 繋ぐ すぐに特定できるようにしています。アーティファクトをスリムに保つため、トレースを絞り込み、ファイルにはビルドIDやコミットIDを含めて確定的な名前を付け、テキスト形式の差分を取得する際は必要に応じてPIDやタイムスタンプを正規化しています。.

よくある落とし穴と解釈のパターン

私は日常的にいくつかの特徴に注意を払っています。呼び出しが中断された場合、しばしば EINTR (信号によって中断)――単発の発生は問題ありませんが、連続して発生する場合は疑わしいです。私が確認した限りでは ERESTARTSYS-のようなメッセージが表示される場合、これはカーネルによってシステムコールが再起動されたことを示唆しています。シグナルの発生源とマスクを確認します。異なるプロセスからの出力が 混ざり合った が表示された場合は、-ff オプションで厳密に分割し、結合にはタイムスタンプを利用します。識別可能な errno- エラーが発生するが、時間的な間隔が長い場合は、I/O やネットワークの待ち時間が原因ではないかと疑う。その場合は、read/write/connect に注目し、計測を追加する。パスが残っている場合は 切り取られた, -s オプションの値をさらに増やすか、または「verbose」表示で省略形を無効にします。32ビット版と64ビット版のバイナリ間に差異が生じた場合(例:. openopenat)、そのアーキテクチャに注意を払い、迷った場合は両方のバリエーションを比較実行します。.

目的を絞った情報の選定:情報の洪水の中で読みやすさを優先する

特にプレッシャーがかかっている時こそ、私は出力を適切に調整するようにしています。具体的には、次のように明確に定義します。 検討課題 (ファイルが見つからない?ネットワークが応答しない?プロセスツリーが破損している?)、その場合は必要最小限のフィルタを設定し、 証拠. チーム引き継ぎの際は、簡潔な 付記 チケットの説明欄には、関連するコール、パラメータ、errno、タイムコンテキスト、および推定される原因を記載します。長時間のセッションでは、すべてのオプションを一度に積み重ねるのではなく、それらを 一歩一歩 手順:まず -e trace=…、次に -tt/-T、続いて -y/-s、必要に応じて -x/-xx。この段階的なアプローチにより、データに溺れることを防ぎ、実際の結論に至るまでの時間を短縮できます。 パフォーマンスが懸念される場合は、フルトレースを実行する前に、-c(および -S time)を使用し、呼び出しの範囲を絞り込むことを好みます。.

コンパクトな概要

と一緒に ストレース 実際のデータを使っているので、エラーの原因をより早く見つけられる システムコール 単なるログテキストを見るだけではありません。フィルタ、タイムスタンプ、そして-cオプションによる統計情報により、パス、権限、ネットワーク、待ち時間に関する明確な手がかりが得られます。プログラムをstraceの下で直接起動するか、実行中のPIDに一時的に接続し、出力を注視して、エラーが確認でき次第停止させます。 後での分析のために、-o および -ff オプションを使ってファイルを書き出し、必要に応じて -s オプションの値を上げ、ホスト間の実行結果を比較して差異を突き止めます。このようにして、Linux サーバーにおける日常的な問題を、数時間ではなく数分で解決しています。.

現在の記事