3.4. クラッシュしたアプリケーションのデバッグ

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

3.4.1. コアダンプ: その概要と使用方法

コアダンプは、アプリケーションの動作が停止した時点のアプリケーションのメモリーの一部のコピーで、ELF 形式で保存されます。コアダンプには、アプリケーションの内部変数、スタックすべてが含まれ、アプリケーションの最終的な状態を検査することができます。それぞれの実行可能ファイルおよびデバッグ情報を追加すると、実行中のプログラムを分析するのと同様に、デバッガーでコアダンプファイルを分析できます。

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

警告

一部の制限は、コアダンプを生成する機能に影響する場合があります。現在の制限を表示するには、次のコマンドを実行します。

$ ulimit -a

3.4.2. コアダンプによるアプリケーションのクラッシュの記録

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

手順

  1. コアダンプを有効にするには、/etc/systemd/system.conf ファイルに以下の行が含まれていることを確認します。

    DumpCore=yes
    DefaultLimitCORE=infinity

    これらの設定が以前に存在したかどうか、以前の値が何であったかを説明するコメントを追加することもできます。これにより、必要に応じて、この変更を後で元に戻すことができます。コメントは、# 文字で始まる行です。

    ファイルを変更するには、管理者レベルのアクセスが必要です。

  2. 新しい設定を適用します。

    # systemctl daemon-reexec
  3. コアダンプサイズの制限を削除します。

    # ulimit -c unlimited

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

  4. システム情報を収集する sosreport ユーティリティーを提供する sos パッケージをインストールします。

    # dnf install sos
  5. アプリケーションがクラッシュすると、コアダンプが生成され、systemd-coredump により処理されます。
  6. SOS レポートを作成して、システムに関する追加情報を提供します。

    # sosreport

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

  7. コアダンプを探してエクスポートします。

    $ coredumpctl list executable-name
    $ coredumpctl dump executable-name > /path/to/file-for-export

    アプリケーションが複数回クラッシュした場合、最初のコマンドの出力には、取得されたコアダンプがさらにリスト表示されます。その場合、2 番目のコマンドに対して、他の情報を使用してより正確なクエリーを作成します。詳細は、man ページ coredumpctl(1) を参照してください。

  8. デバッグを行うコンピューターに、コアダンプと SOS レポートを移動します。既知の場合は、実行ファイルも転送します。

    重要

    実行可能ファイルが不明な場合は、コアファイルのその後の分析で特定します。

  9. オプション: コアダンプと SOS レポートに移動後に削除して、ディスク領域を解放します。

3.4.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. モジュールのビルド ID、およびメモリー内の場所
    3. モジュールの実行ファイル名 - 不明の場合は -、モジュールがファイルから読み込まれていない場合は . と表示されます。
    4. デバッグ情報のソース - 使用可能な場合はファイル名が表示されます。実行ファイル自体に含まれている場合は .、存在しない場合は - と表示されます。
    5. 主要なモジュールの共有ライブラリー名 (soname) または [exe]

    この例では、重要な詳細は、テキスト [exe] を含む行のファイル名 /usr/bin/sleep と、ビルド ID 2818b2009547f780a5639c904cded443e564973e です。この情報を使用して、コアダンプの分析に必要な実行可能ファイルを特定できます。

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

    • 可能であれば、クラッシュが発生したシステムからコピーします。コアファイルから抽出したファイル名を使用します。
    • システムで同じ実行ファイルを使用することもできます。Red Hat Enterprise Linux にビルドされた実行ファイルはそれぞれ、固有の build-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 が実行中のプロセスに割り当てられる訳ではありません。実行を制御するコマンドは影響を受けません。

関連情報

3.4.4. coredumpctl を使用したコアダンプの作成およびアクセス

systemdcoredumpctl ツールは、クラッシュが発生したマシン上のコアダンプの処理を大幅に合理化できます。この手順では、応答しないプロセスのコアダンプを取得する方法を説明します。

前提条件

  • システムは、コアダンプの処理に systemd-coredump を使用するように設定している。true かどうか確認するには、次のコマンドを実行します。

    $ sysctl kernel.core_pattern

    次の内容で出力が始まる場合は、設定が適切です。

    kernel.core_pattern = |/usr/lib/systemd/systemd-coredump

手順

  1. 実行ファイル名の既知の部分に基づいて、ハングしたプロセスの PID を検索します。

    $ pgrep -a executable-name-fragment

    このコマンドは、フォームの行を出力します。

    PID command-line

    command-line 値を使用して、PID が目的のプロセスに属することを確認します。

    以下に例を示します。

    $ pgrep -a bc
    5459 bc
  2. 中断シグナルをプロセスに送信します。

    # kill -ABRT PID
  3. コアが coredumpctl で取得されていることを確認します。

    $ coredumpctl list PID

    以下に例を示します。

    $ coredumpctl list 5459
    TIME                            PID   UID   GID SIG COREFILE  EXE
    Thu 2019-11-07 15:14:46 CET    5459  1000  1000   6 present   /usr/bin/bc
  4. 必要に応じて、コアファイルをさらに検証または使用します。

    PID と他の値でコアダンプを指定できます。詳細は、man ページの coredumpctl(1) を参照してください。

    • コアファイルの詳細を表示します。

      $ coredumpctl info PID
    • GDB デバッガーでコアファイルを読み込むには、次のコマンドを実行します。

      $ coredumpctl debug PID

      デバッグ情報の可用性によっては、GDB は次のようなコマンドを実行するコマンドを提案します。

      Missing separate debuginfos, use: dnf debuginfo-install bc-1.07.1-5.el8.x86_64

      このプロセスの詳細は、GDB を使用したアプリケーションまたはライブラリーの debuginfo パッケージの取得 を参照してください。

    • その後の処理を別の場所でするためにコアファイルをエクスポートするには、次のコマンドを実行します。

      $ coredumpctl dump PID > /path/to/file_for_export

      /path/to/file_for_export を、コアダンプを配置するファイルに置き換えます。

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

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

前提条件

  • コアダンプの概要および作成方法を理解している。
  • GDB がシステムにインストールされている。

手順

  1. プロセス ID (pid) を検索します。pspgreptop などのツールを使用します。

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

    $ gcore -o filename pid

    これでファイル filename が作成され、その中にプロセスメモリーがダンプされます。メモリーをダンプしている間は、プロセスの実行は停止します。

  3. コアダンプが終了すると、プロセスは通常の実行を再開します。
  4. SOS レポートを作成して、システムに関する追加情報を提供します。

    # sosreport

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

  5. デバッグを行うコンピューターに、プログラムの実行ファイル、コアダンプ、および SOS レポートを移動します。
  6. オプション: コアダンプと SOS レポートに移動後に削除して、ディスク領域を解放します。

関連情報

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

プロセスのメモリーをダンプしないようにマークできます。これにより、銀行、会計アプリケーション、または仮想マシン全体など、プロセスメモリーに機密データが含まれる場合は、リソースを節約し、セキュリティーを強化できます。カーネルのコアダンプ (kdump) および手動のコアダンプ (gcore、GDB) は、このようにマークされたメモリーをダンプしません。

場合によっては、これらの保護に関係なく、プロセスメモリーの内容全体をダンプする必要があります。この手順では、GDB デバッガーを使用してこれを行う方法を説明します。

前提条件

  • コアダンプとは何かを理解する必要がある。
  • 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 を、メモリーをダンプするファイルの名前に置き換えます。

関連情報