20.3. アプリケーションの対話の記録

アプリケーションの実行可能コードは、オペレーティングシステムや共有ライブラリーのコードと対話します。これらの対話に関するアクティビティーログを記録すると、実際のアプリケーションコードをデバッグせずに、アプリケーションの動作を詳細にわたり知ることができます。また、アプリケーションの対話を分析すると、バグが発生した状況をピンポイントで特定しやすくなります。

20.3.1. アプリケーションの対話の記録に役立つツール

Red Hat Enterprise Linux には、アプリケーションの対話を分析するための複数のツールが含まれます。

strace

strace ツールは主に、アプリケーションが使用するシステム呼び出し (カーネル関数) のログ記録を有効にします。

  • strace は、パラメーターを解釈し、基礎となるカーネルコードに関する知識が得られるため、strace の出力と呼び出しの詳しい情報を提供します。数値は、定数名、フラグリストに展開されたビット単位の結合フラグ、実際の文字列を提供するために逆参照された文字配列へのポインターなどにそれぞれ変換されます。最新のカーネル機能のサポートがない場合があります。
  • トレースされた呼び出しをフィルタリングして、取得するデータ量を減らすことができます。
  • [command]`strace を使用するために、ログフィルターの設定以外に、特別な設定は必要ありません。
  • strace でアプリケーションコードを追跡すると、アプリケーションの実行速度が大幅に遅くなるため、strace は、多くの実稼働環境のデプロイメントには適しません。代替方法として、ltrace または SystemTap の使用を検討してください。
  • Red Hat Developer Toolset で利用可能な strace のバージョンでは、システム呼び出しで異なる結果を出すこともできます。そのため、この機能はデバッグに役立ちます。
ltrace

ltrace ツールを使用すると、アプリケーションのユーザー空間呼び出しのログを共有オブジェクト (動的ライブラリー) に記録できます。

  • ltrace は、ライブラリーへの呼び出しを追跡できるようにします。
  • トレースされた呼び出しをフィルタリングして、取得するデータ量を減らすことができます。
  • ltrace を使用するために、ログフィルターの設定以外に、特別な設定は必要ありません。
  • ltrace は、軽量、高速で、 strace の代わりとして使用できます。strace でカーネル関数を追跡する代わりに、ltraceglibc などのライブラリー内の各インターフェースを追跡できます。
  • ltracestrace などの既知の呼び出しを処理しないので、ライブラリーの関数に渡す値の情報は提供されません。ltrace の出力には、生の数値およびポインターのみが含まれます。ltrace の出力の解釈には、出力にあるライブラリーの実際のインターフェース宣言を確認する必要があります。
SystemTap

SystemTap は、Linux システム上で実行中のプロセスおよびカーネルアクティビティーを調査するための有用なインストルメンテーションプラットフォームです。SystemTap は、独自のスクリプト言語を使用してカスタムイベントハンドラーをプログラミングします。

  • straceltrace の使用と比較した場合、ロギングのスクリプトを作成すると、初期の設定フェーズでより多くの作業が必要になります。ただし、スクリプト機能は単にログを生成するだけでなく、SystemTap の有用性を高めます。
  • SystemTap は、カーネルモジュールを作成し、挿入すると機能します。SystemTap は効率的に使用でき、システムまたはアプリケーションの実行速度が大幅に低下することはありません。
  • SystemTap には一連の使用例が提供されます。
GDB

GNU デバッガーは主に、ロギングではなく、デバッグを目的としています。ただし、その機能の一部は、アプリケーションの対話が主要なアクティビティーとなるシナリオでも役に立ちます。

  • GDB では、対話イベントを取得して、後に続く実行パスを即時にデバッグするように、都合よく組み合わせることができます。
  • GDB は、他のツールで問題のある状況を最初に特定した後、頻度の低いイベントや特異なイベントへの応答を分析するのに最適です。イベントが頻繁に発生するシナリオで GDB を使用すると、効率が悪くなったり、不可能になったりします。
関連情報

20.3.2. strace でのアプリケーションのシステム呼び出しの監視

strace ツールは、アプリケーションを実行するシステム (カーネル) 呼び出しの監視を有効にします。

前提条件
手順
  1. 監視するシステム呼び出しを特定します。
  2. 監視するプログラムが実行していない場合は、strace を起動して、プログラム を指定します。

    $ strace -fvttTyy -s 256 -e trace=call program

    call を、表示するシステム呼び出しに置き換えます。-e trace=call オプションは複数回使用できます。何も指定しない場合、strace はすべてのシステム呼び出しタイプを表示します。詳しい情報は、strace(1) の man ページを参照してください。

    プログラムがすでに実行中の場合は、プロセス id (pid) を検索して、その id に strace を割り当てます。

    $ ps -C program
    (...)
    $ strace -fvttTyy -s 256 -e trace=call -ppid

    フォークしたプロセスまたはスレッドを追跡しない場合には、-f オプションは指定しないでください。

  3. strace は、アプリケーションで作成したシステム呼び出しとその詳細を表示します。

    ほとんどの場合、システム呼び出しのフィルターが設定されていないと、アプリケーションとそのライブラリーは多数の呼び出しを行い、strace 出力がすぐに表示されます。

  4. strace は、プログラムの終了時に終了します。

    追跡しているプログラムの終了前に監視を中断するには、ctrl+C を押します。

    • strace でプログラムを起動すると、そのプログラムは strace と共にに中断します。
    • 実行中のプログラムに strace を割り当てると、そのプログラムは strace と共に中断します。
  5. アプリケーションが実行したシステム呼び出しの一覧を分析します。

    • リソースへのアクセスや可用性の問題は、エラーを返す呼び出しとしてログに表示されます。
    • システム呼び出しや呼び出しシーケンスのパターンに渡す値により、アプリケーションの動作の原因が分かります。
    • アプリケーションがクラッシュした場合に、重要な情報はおそらく、ログの最後に表示されます。
    • 出力には不要な情報が多く含まれています。ただし、より正確なフィルターを作成して、手順を繰り返すことができます。
注記

出力を確認することにも、ファイルに保存することにも利点があります。これを実行するには、tee コマンドを使用します。

$ strace ... |& tee your_log_file.log
関連情報

20.3.3. ltrace でのアプリケーションのライブラリー関数呼び出しの監視

ltrace ツールは、ライブラリー (共有オブジェクト) で利用可能な関数に対するアプリケーションの呼び出しを監視できます。

前提条件
手順
  1. 可能であれば、対象のライブラリーおよび関数を特定します。
  2. 監視するプログラムが実行されていない場合には、ltrace を起動して、プログラム を指定します。

    $ ltrace -f -l library -e function program

    -e および -l のオプションを使用して、出力をフィルタリングします。

    • function として表示される関数の名前を指定します。-e function オプションは複数回使用できます。何も指定しない場合は、ltrace はすべての関数への呼び出しを表示します。
    • 関数を指定するのではなく、-l library オプションでライブラリー全体を指定することができます。このオプションは、-e function オプションと同じように動作します。

    詳細情報は、man ページの ltrace(1) を参照してください。

    プログラムがすでに実行中の場合は、プロセス id (pid) を検索して、その id に ltrace を割り当てます。

    $ ps -C program
    (...)
    $ ltrace ... -ppid

    フォークしたプロセスまたはスレッドを追跡しない場合には、-f オプションは指定しないでください。

  3. ltrace はアプリケーションのライブラリー呼び出しを表示します。

    多くの場合、アプリケーションは大量の呼び出しを作成し、フィルターが設定されていない場合には、ltrace の出力がすぐに表示されます。

  4. ltrace は、プログラムが終了すると終了します。

    追跡しているプログラムの終了前に監視を中断するには、ctrl+C を押します。

    • ltrace でプログラムを起動した場合には、プログラムは ltrace と共に中断します。
    • 実行中のプログラムに ltrace を割り当てると、プログラムは ltrace と共に終了します。
  5. アプリケーションが実行したライブラリー呼び出しの一覧を分析します。

    • アプリケーションがクラッシュした場合に、重要な情報はおそらく、ログの最後に表示されます。
    • 出力には不要な情報が多く含まれています。ただし、より正確なフィルターを作成して、手順を繰り返すことができます。
注記

出力を確認することにも、ファイルに保存することにも利点があります。これを実行するには、tee コマンドを使用します。

$ ltrace ... |& tee your_log_file.log
関連情報
  • strace(1) man ページ
  • Red Hat Developer Toolset User Guide: 「ltrace」の章

20.3.4. SystemTap でのアプリケーションのシステム呼び出しの監視

SystemTap ツールを使用すると、カーネルイベントにカスタムイベントハンドラーを登録できます。strace と比較すると、これは使いにくくなりますが、効率性は高く、より複雑な処理ロジックを使用することができます。

前提条件
手順
  1. 以下の内容を含む my_script.stp ファイルを作成します。

    probe begin
    {
      printf("waiting for syscalls of process %d \n", target())
    }
    
    probe syscall.*
    {
      if (pid() == target())
        printf("%s(%s)\n", name, argstr)
    }
    
    probe process.end
    {
      if (pid() == target())
        exit()
    }
  2. 監視するプロセスのプロセス ID (pid) を検索します。

    $ ps -aux
  3. スクリプトで SystemTap を実行します。

    # stap my_script.stp -x pid

    pid の値は、プロセス ID です。

    スクリプトはカーネルモジュールにコンパイルされ、それが読み込まれます。これにより、コマンドの入力から出力の取得までにわずかな遅延が生じます。

  4. プロセスでシステム呼び出しが実行されると、呼び出し名とパラメーターがターミナルに出力されます。
  5. プロセスが終了した場合、または Ctrl+C を押すと、スクリプトは終了します。
関連情報

20.3.5. GDB を使用したアプリケーションシステム呼び出しの遮断

GDB は、プログラムの実行中に発生するさまざまな状況において実行を停止することができます。プログラムがシステム呼び出しを実行する際に実行を停止するには、GDB catchpoint を使用します。

前提条件

GDB の使用によるシステム呼び出しでのプログラム実行の停止

  1. キャッチポイントを設定します。

    (gdb) catch syscall syscall-name

    catch syscall コマンドは、プログラムがシステム呼び出しを実行する際に実行を停止する特殊なタイプのブレークポイントを設定します。

    syscall-name オプショは、呼び出し名を指定します。様々なシステム呼び出しに対して複数のキャッチポイントを指定することができます。syscall-name オプションに何も指定しない場合には、システム呼び出しがあると GDB が停止してしまいます。

  2. プログラムが実行を開始していない場合は、これを開始します。

    (gdb) r

    プログラムの実行が一時停止しているだけの場合は、これを再開します。

    (gdb) c
  3. GDB は、指定のシステム呼び出しがプログラムによって実行された後に実行を一時停止します。
関連情報

20.3.6. アプリケーションによるシグナル処理を遮断するための GDB の使用

GDB は、プログラムの実行中に発生するさまざまな状況において実行を停止することができます。プログラムがオペレーティングシステムからシグナルを受信した時に実行を停止するには、GDB の キャッチポイント を使用します。

前提条件
GDB でのシグナル受信時のプログラム実行の停止
  1. キャッチポイントを設定します。

    (gdb) catch signal signal-type

    catch signal コマンドは、プログラムがシステム呼び出しを受信する際に実行を停止する特殊なタイプのブレークポイントを設定します。signal-type オプションは、シグナルのタイプを指定します。すべてのシグナルを取得するには、特殊な値 all を使用します。

  2. プログラムが実行を開始していない場合は、これを開始します。

    (gdb) r

    プログラムの実行が一時停止しているだけの場合は、これを再開します。

    (gdb) c
  3. GDB は、プログラムが指定のシグナルを受けると実行を停止します。
関連情報