第21章 クラッシュしたアプリケーションのデバッグ

アプリケーションを直接デバッグできない場合があります。そのような場合には、中断時のアプリケーションの情報を収集して、後で分析することができます。

21.1. コアダンプ

以下のセクションでは、コアダンプ の概要、その用途について説明します。

前提条件

  • デバッグ情報を理解していること

説明

コアダンプは、アプリケーション機能が停止した時点のアプリケーションメモリーの一部を ELF 形式で保存したコピーのことです。コアダンプには、アプリケーションの内部変数、スタックすべてが含まれ、アプリケーションの最終的な状態を検査することができます。適切な実行ファイルやデバッグ情報が指定されている場合には、実行中のプログラムを分析するのに似た方法で、デバッガーを使用してコアダンプファイルを分析することができます。

Linux オペレーティングシステムのカーネルは、コアダンプの自動記録が有効化去れている場合には、コアダンプを自動的に記録できます。また、実行中のアプリケーションにシグナルを送り、実際の状態に関係なくコアダンプを生成することも可能です。

警告

コアダンプの生成機能に影響を与える制限が何点かあります。

21.2. コアダンプでのアプリケーションのクラッシュの記録

アプリケーションのクラッシュを記録するには、コアダンプの保存内容を設定し、システムに関する情報を追加します。

ステップ

  1. コアダンプを有効にします。/etc/systemd/systemd.conf ファイルを編集し、DefaultLimitCORE を含む行を以下のように変更します。

    DefaultLimitCORE=infinity
  2. システムを再起動します。

    # shutdown -r now
  3. コアダンプサイズの制限を削除します。

    # ulimit -c unlimited

    この変更を元に戻すには、unlimited の代わりに 0 を指定してコマンドを実行します。

  4. アプリケーションがクラッシュすると、コアダンプが生成されます。コアダンプのデフォルトの場所は、クラッシュ発生時の作業ディレクトリーとなっています。
  5. システムに関する追加情報を指定するには、SOS レポートを作成します。

    # sosreport

    これにより、設定ファイルのコピーなど、お使いのシステムに関する情報が含まれる tar アーカイブが作成されます。

  6. デバッグを行うコンピューターに、コアダンプと SOS レポートを移動します。また、実行可能ファイルがある場合にはそのファイルも移動します。

    重要

    実行可能ファイルが不明な場合は、あとでコアファイルを分析するときに特定します。

  7. オプション: コアダンプと SOS レポートに移動後には、ディスク容量を開放するために削除します。

関連資料

21.3. コアダンプを使用したアプリケーションのクラッシュの状態の検証

前提条件

  • コアダンプファイルおよび sosreport
  • GDB および elfutils がシステムにインストールされていること

ステップ

  1. クラッシュが発生した実行可能ファイルを特定するには、コアダンプファイルを指定して、eu-unstrip コマンドを実行します。

    $ eu-unstrip -n --core=./core.9814
    0x400000+0x207000 2818b2009547f780a5639c904cded443e564973e@0x400284 /usr/bin/sleep /usr/lib/debug/bin/sleep.debug [exe]
    0x7fff26fff000+0x1000 1e2a683b7d877576970e4275d41a6aaec280795e@0x7fff26fff340 . - linux-vdso.so.1
    0x35e7e00000+0x3b6000 374add1ead31ccb449779bc7ee7877de3377e5ad@0x35e7e00280 /usr/lib64/libc-2.14.90.so /usr/lib/debug/lib64/libc-2.14.90.so.debug libc.so.6
    0x35e7a00000+0x224000 3ed9e61c2b7e707ce244816335776afa2ad0307d@0x35e7a001d8 /usr/lib64/ld-2.14.90.so /usr/lib/debug/lib64/ld-2.14.90.so.debug ld-linux-x86-64.so.2

    出力には、行ごとに各モジュールの詳細が、スペースで区切られて表示されます。以下の順番で情報が表示されます。

    1. モジュールがマッピングされているメモリーアドレス
    2. モジュールの build-id および、その id が見つかったメモリーの場所
    3. 不明な場合は -、モジュールがファイルから読み込まれていない場合には . として表示される、モジュールの実行可能ファイル名
    4. 実行可能ファイル自体に含まれている場合には .、ファイルが存在しない場合には - のファイル名で表示されるデバッグ情報のソース
    5. 主要なモジュールの共有ライブラリー名 (soname) または [exe]

    この例では、重要な情報は /usr/bin/sleep と、[exe] テキストに含まれる行の build-id 2818b2009547f780a5639c904cded443e564973e です。この情報を使用して、コアダンプの分析に日宇町な実行可能ファイルを特定することができます。

  2. クラッシュした実行可能ファイルを取得します。

    • 可能であれば、クラッシュが発生したシステムからコピーします。コアファイルから取得したファイル名を使用します。
    • または、お使いのシステムで、同じ実行可能ファイルを使用します。Red Hat Enterprise Linux でビルドされた実行可能ファイルはそれぞれ、一意の buid-id の値と中期が含まれます。build-id がローカルで利用可能で適切な実行可能ファイルであるこかどうかを判断します。

      $ eu-readelf -n executable_file

      この情報を使用して、リモートシステムの実行可能ファイルとローカルコピーを一致させます。ローカルファイルの build-id と、コアダンプに表示される build-id は必ず一致させてください。

    • 最後に、アプリケーションが RPM パッケージからインストールされた場合には、パッケージから実行可能ファイルを取得できます。sosreport の出力を使用して、必要なパッケージと合致するバージョンを検索します。
  3. 実行可能ファイルで使用する共有ライブラリーを取得します。実行可能ファイルと同じ手順を使用します。
  4. アプリケーションがパッケージとして配信されている場合は、GDB で実行可能ファイルを読み込み、足りない debuginfo パッケージに関するヒントを表示します。詳細は、「GDB を使用したアプリケーションまたはライブラリー向けの debuginfo パッケージ取得」を参照してください。
  5. コアファイルを詳細にわたり検証するには、GDB で実行可能ファイルとコアダンプファイルを読み込みます。

    $ gdb -e executable_file -c core_file

    足りないファイルやデバッグ情報に関するさらなるメッセージで、デバッグセッションで足りない情報の特定に役立ちます。必要に応じて、以前の手順に戻ります。

    アプリケーションのデバッグ情報がパッケージのではなく、ファイルとして提供される場合には、symbol-file コマンドを使用して、このファイルを GDB で読み込みます。

    (gdb) symbol-file program.debug

    program.debug は実際のファイル名に置き換えます。

    注記

    コアダンプに含まれるすべての実行可能ファイルにデバッグ情報をインストールする必要はありません。これらの実行可能ファイルの多くは、アプリケーションコードで使用するライブラリーです。これらのライブラリーが、分析中の問題の直接原因でない可能性があるので、ライブラリーのデバッグ情報を含める必要はありません。

  6. GDB コマンドを使用して、クラッシュした時点のアプリケーションの状態を検証します。「GDB を使用したアプリケーションの内部状況の検証」を参照してください。

    注記

    コアファイルを分析する場合は、実行中のプロセスに、GDB はアタッチしません。実行を制御するコマンドを使用しても効果がありません。

関連資料

21.4. gcore を使用したプロセスメモリーのダンプ

コアダンプのデバッグに関するワークフローでは、プログラムの状態をオフラインで分析できます。対象のプロセスで環境にアクセスするのが困難な場合など、実行中のプログラムでこのワークフローを使用すると有益な場合があります。gcore コマンドを使用して、実行中にプロセスのメモリーをダンプすることができます。

前提条件

ステップ

gcore を使用してプロセスメモリーをダンプします。

  1. プロセス id (pid) を検索します。pspgrep および top などのツールを使用します。

    $ ps -C some-program
  2. このプロセスのメモリーをダンプします。

    $ gcore -o filename pid

    このコマンドで、filename を作成し、このファイルにプロセスメモリーをダンプします。

  3. コアダンプが完了したら、プロセスで通常の実行が再開されます。
  4. システムに関する追加情報を指定するには、SOS レポートを作成します。

    # sosreport

    これにより、設定ファイルのコピーなど、お使いのシステムに関する情報が含まれる tar アーカイブが作成されます。

  5. デバッグを行うコンピューターに、プログラムの実行可能ファイル、コアダンプ、SOS レポートを移動します。
  6. オプション: コアダンプと SOS レポートに移動後には、ディスク容量を開放するために削除します。

関連資料

21.5. GDB での保護されたプロセスメモリーのダンプ

プロセスのメモリーをダンプしないように、マークすることができます。カーネルコアダンプ (kdump) や手動のコアダンプ (gcore、GDB) は、このようにマークされたメモリーをダンプしません。

このように保護されていても、プロセスメモリーの全コンテンツをダンプする必要がある場合があります。以下の手順では、GDB デバッガーを使用して、全コンテンツをダンプする方法を説明します。

前提条件

ステップ

  1. /proc/PID/coredump_filter ファイルの設定を無視するように GDB を設定します。

    (gdb) set use-coredump-filter off
  2. メモリーページのフラグ VM_DONTDUMP を無視するように GDB を設定します。

    (gdb) set dump-excluded-mappings on
  3. メモリーをダンプします。

    (gdb) gcore core-file

    core-file は、メモリーをダンプする先のファイル名に置き換えます。

関連資料