第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 でデバッグ情報の作成を有効にするには、-a
オプションを使用します。
$ gcc ... -g ...
-
コンパイラーとリンカーで最適化を行うと、実行可能なコードを、元のソースコードと関連付けることが難しくなります。変数の最適化、ループのアンロール、周りの操作へのマージなどが行われる可能性があります。これにより、デバッグに負の影響が及ぶ可能性があります。デバッグの体験を向上するには、
-Og
オプションを指定して、最適化を設定することを考慮してください。ただし、最適化レベルを変更すると、実行可能なコードが変更され、バグを取り除くための実際の動作が変更される可能性があります。 -
-fcompare-debug
GCC オプションでは、GCC でコンパイルしたコードを、デバッグ情報を使用して (または、デバッグ情報を使用せずに) テストします。このテストでは、出力されたバイナリーファイルの 2 つが同一であれば合格します。このテストを行うことで、実行可能なコードがデバッグオプションによる影響は受けないようにするだけでなく、デバッグコードにバグが含まれないようにします。-fcompare-debug
オプションを使用するとコンパイルの時間が大幅に伸びることに留意してください。このオプションに関する詳細は、GCC の man ページを参照してください。
関連情報
- 「デバッグ情報を使用したデバッグの有効化」
- GNU コンパイラーコレクション (GCC) の使用: 3.10 Options for Debugging Your Program
- GDB でのデバッグ: 18.3 Debugging Information in Separate Files
GCC の man ページ:
$ man gcc
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) は、自動的に足りないデバッグ情報を認識して、パッケージ名を解決します。
前提条件
- デバッグするアプリケーションまたはライブラリーがシステムにインストールされていること
- システムに GDB がインストールされていること
-
システムに
debuginfo-install
ツールがインストールされていること
手順
デバッグするアプリケーションまたはライブラリーに割り当てられた 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)
これ以上先に進まずに GDB を終了します。 q を入力して、Enter を押します。
(gdb) q
GDB が提案するコマンドを実行して、必要な debuginfo パッケージをインストールします。
# debuginfo-install coreutils-8.22-21.el7.x86_64
アプリケーションまたはライブラリーの debuginfo パッケージをインストールすると、すべての依存関係の debuginfo パッケージもインストールされます。
-
GDB が debuginfo パッケージを提案できない場合には、「手動でのアプリケーションまたはライブラリー向けの
debuginfo
パッケージの取得」 の手順に従ってください。
関連情報
- Red Hat Developer Toolset User Guide: Installing Debugging Information
- Red Hat ナレッジベースソリューション: RHEL システムで debuginfo パッケージをダウンロードまたはインストールする
20.1.5. 手動でのアプリケーションまたはライブラリー向けの debuginfo
パッケージの取得
インストール用にどの debuginfo
パッケージをインストールするのかを手作業で選択するには、実行ファイルの場所を特定して、インストールするパッケージを検索します。
GDB を使用してインストール用のパッケージを決定すること を推奨します。この手動の手順は、GDB がインストールするパッケージを提案できない場合にのみ使用してください。
前提条件
- アプリケーションまたはライブラリーをシステムにインストールしている。
-
debuginfo
-install ツールは、システムで利用できるようにする必要がある。
手順
アプリケーションまたはライブラリーの実行可能ファイルを検索します。
which
コマンドを使用して、アプリケーションファイルを検索します。$ which nautilus /usr/bin/nautilus
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
ファイルパスを使用して、対象のファイルを提供するパッケージを検索します。
# 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.architecture
の形式でパッケージのリストが表示されます。yum
の出力で表示されるバージョンは実際にインストールされているバージョンでない場合があるので、この手順では、パッケージの 名前 のみが重要です。重要この手順では結果が返されないので、どのパッケージがバイナリーファイル用のパッケージであるか、またこの手順が失敗したかどうかを判別することができません。
rpm
の低レベルのパッケージ管理ツールを使用して、どのパッケージバージョンがシステムにインストールされているかを確認します。パッケージ名を引数として使用します。$ rpm -q zlib zlib-1.2.7-17.el7.x86_64
この出力では、
name-version.distribution.architecture
の形式でインストールされたパッケージの詳細が表示されます。debuginfo-install
ユーティリティーを使用してdebuginfo
パッケージをインストールします。このコマンドで、直前の手順で確認したパッケージ名およびその他の詳細情報を使用します。# debuginfo-install zlib-1.2.7-17.el7.x86_64
アプリケーションまたはライブラリーの
debuginfo
パッケージをインストールすると、すべての依存関係のdebuginfo
パッケージもインストールされます。
関連資料
- Red Hat Developer Toolset User Guide: Installing Debugging Information
- ナレッジベースアーティクル: RHEL システムで debuginfo パッケージをダウンロードまたはインストールする