第20章 実行中のアプリケーションのデバッグ

本章では、開発者が直接アクセスできるマシンで、必要に応じて何度でも起動できるアプリケーションのデバッグ方法を紹介します。

20.1. デバッグ情報を使用したデバッグの有効化

アプリケーションおよびライブラリーをデバッグするには、デバッグ情報が必要です。以下のセクションでは、この情報を取得する方法を説明します。

20.1.1. デバッグの情報

実行可能なコードをデバッグする場合に、ツールやプログラマーは 2 種類の情報を使用して、バイナリーコードを理解することができます。

  • ソースコードテキスト
  • ソースコードテキストがバイナリーコードにどのように関連しているのかの説明

上記はデバッグ情報と呼ばれます。

Red Hat Enterprise Linux は、実行可能なバイナリー、共有ライブラリー、または debuginfo ファイルに ELF 形式を使用します。これらの ELF ファイル内では、DWARF 形式を使用してデバッグ情報が保持されます。

DWARF シンボルは、readelf -w file コマンドを使用して読み込みます。

注意

STABS は UNIX で使用される場合もあります。STABS は、機能が少ない旧式の形式です。Red Hat はこの使用を推奨していません。GCC および GDB では、STABS の実稼働および使用はベストエフォートでのみサポートされます。Valgrind および elfutils などの他のツールでは、STABS のサポートはありません。

関連情報

20.1.2. GCC を使用した C および C++ アプリケーションのデバッグの有効化

デバッグ情報のサイズが大きい場合、その情報はデフォルトで実行可能ファイルに含まれません。GCC を使用した C および C++ のアプリケーションのデバッグを有効にするには、コンパイラーに対して、ファイルを作成するように、明示的に指示する必要があります。

GCC を使用したデバッグ情報の作成の有効化

コードのコンパイルおよびリンク時に GCC でデバッグ情報の作成を有効にするには、-g オプションを使用します。

$ gcc ... -g ...
  • コンパイラーとリンカーで最適化を行うと、実行可能なコードを、元のソースコードと関連付けることが難しくなります。変数の最適化、ループのアンロール、周りの操作へのマージなどが行われる可能性があります。これにより、デバッグに負の影響が及ぶ可能性があります。デバッグを容易にするために、-Og オプションを指定して最適化を設定することを考慮してください。ただし、最適化レベルを変更すると、実行可能なコードが変更され、バグを取り除くための実際の動作が変更される可能性があります。
  • -fcompare-debug GCC オプションでは、GCC でコンパイルしたコードを、デバッグ情報を使用して (または、デバッグ情報を使用せずに) テストします。このテストでは、出力されたバイナリーファイルの 2 つが同一であれば合格します。このテストを行うことで、実行可能なコードがデバッグオプションによる影響は受けないようにするだけでなく、デバッグコードにバグが含まれないようにします。-fcompare-debug オプションを使用するとコンパイルの時間が大幅に伸びることに留意してください。このオプションに関する詳細は、GCC の man ページを参照してください。
関連情報

20.1.3. Debuginfo パッケージ

Debuginfo パッケージには、プログラムとライブラリーのデバッグ情報と、デバッグソースコードが含まれます。

前提条件
Debuginfo パッケージ

Red Hat Enterprise Linux リポジトリーのパッケージにインストールされているアプリケーションやライブラリーの場合は、別のチャンネルで提供されている別の debuginfo パッケージとしてデバッグ情報とデバッグソースコードを取得することができます。debuginfo パッケージには .debug ファイルが含まれており、その中には、バイナリーパッケージのコンパイルに使用する DWARF debuginfo とソースファイルがあります。Debuginfo パッケージのコンテンツは、/usr/lib/debug ディレクトリーにインストールされます。

debuginfo パッケージでは、名前、バージョン、リリース、アーキテクチャーが同じバイナリーパッケージでのみ有効なデバッグ情報が提供されます。

  • バイナリーパッケージ: packagename-version-release.architecture.rpm
  • debuginfo パッケージ: packagename-debuginfo-version-release.architecture.rpm

20.1.4. GDB を使用したアプリケーションまたはライブラリー向けの debuginfo パッケージの取得

GNU デバッガー (GDB) は、自動的に足りないデバッグ情報を認識して、パッケージ名を解決します。

前提条件
手順
  1. デバッグするアプリケーションまたはライブラリーに割り当てられた GDB を起動します。GDB は不足しているデバッグ情報を自動的に認識し、実行するコマンドを提案します。

    $ gdb -q /bin/ls
    Reading symbols from /usr/bin/ls...Reading symbols from /usr/bin/ls...(no debugging symbols found)...done.
    (no debugging symbols found)...done.
    Missing separate debuginfos, use: debuginfo-install coreutils-8.22-21.el7.x86_64
    (gdb)
  2. これ以上先に進まずに GDB を終了します。 q を入力して、Enter を押します。

    (gdb) q
  3. GDB が提案するコマンドを実行して、必要な debuginfo パッケージをインストールします。

    # debuginfo-install coreutils-8.22-21.el7.x86_64

    アプリケーションまたはライブラリーの debuginfo パッケージをインストールすると、すべての依存関係の debuginfo パッケージもインストールされます。

  4. GDB が debuginfo パッケージを提案できない場合には、 「手動でのアプリケーションまたはライブラリー向けの debuginfo パッケージの取得」の手順に従ってください。
関連情報

20.1.5. 手動でのアプリケーションまたはライブラリー向けの debuginfo パッケージの取得

実行可能ファイルの場所を特定し、そのファイルをインストールするパッケージを検索して、インストール用の debuginfo パッケージを手動で判別できます。

注記

GDB を使用してインストール用のパッケージを決定すること を推奨します。この手動の手順は、GDB がインストールするパッケージを提案できない場合にのみ使用してください。

前提条件
手順
  1. アプリケーションまたはライブラリーの実行可能ファイルを検索します。

    1. which コマンドを使用して、アプリケーションファイルを検索します。

      $ which nautilus
      /usr/bin/nautilus
    2. locate コマンドを使用して、ライブラリーファイルを検索します。

      $ locate libz | grep so
      /usr/lib64/libz.so
      /usr/lib64/libz.so.1
      /usr/lib64/libz.so.1.2.7

      デバッグの元の理由にエラーメッセージが含まれている場合、ライブラリーのファイル名に同じ追加の数字が含まれる結果を選択します。不明な点がある場合は、ライブラリーファイルの名前に追加の番号が含まれていないものを使用して、残りの手順を試してください。

      注記

      locate コマンドは mlocate パッケージで提供されます。このパッケージをインストールして、その使用を有効にするには、以下のコマンドを実行します。

      # yum install mlocate
      # updatedb
  2. ファイルパスを使用して、対象のファイルを提供するパッケージを検索します。

    # yum provides /usr/lib64/libz.so.1.2.7
    Loaded plugins: product-id, search-disabled-repos, subscription-manager
    zlib-1.2.7-17.el7.x86_64 : The compression and decompression library
    Repo        : @anaconda/7.4
    Matched from:
    Filename    : /usr/lib64/libz.so.1.2.7

    この出力では、name-version.distribution.platform の形式でパッケージの一覧が表示されます。yum の出力で表示されるバージョンは実際にインストールされているバージョンでない場合があるので、この手順では、パッケージの 名前 のみが重要です。

    重要

    この手順では結果が返されないので、どのパッケージがバイナリーファイル用のパッケージであるか、またこの手順が失敗したかどうかを判別することができません。

  3. rpm の低レベルのパッケージ管理ツールを使用して、どのパッケージバージョンがシステムにインストールされているかを確認します。パッケージ名を引数として使用します。

    $ rpm -q zlib
    zlib-1.2.7-17.el7.x86_64

    この出力では、name-versiondistribution.platform の形式でインストールされたパッケージの詳細が表示されます。

  4. debuginfo-install ユーティリティーを使用して debuginfo パッケージをインストールします。このコマンドで、直前の手順で確認したパッケージ名およびその他の詳細情報を使用します。

    # debuginfo-install zlib-1.2.7-17.el7.x86_64

    アプリケーションまたはライブラリーの debuginfo パッケージをインストールすると、すべての依存関係の debuginfo パッケージもインストールされます。

関連情報