第5章 デバッグ

通常、有用で質の高いソフトウェアは、アプリケーション開発の複数フェーズを経て作成されるため、その間にミスについての十分な機会が設けられます。一部のフェーズには、エラーを検出する一連のメカニズムがそれぞれ設定されています。たとえば、変数や関数などのオブジェクトが適切に記述されていることを確認するために、コンパイル時に基本的なセマンティクス解析が行われます。
アプリケーション開発の各フェーズで実行されるエラーチェックのメカニズムは、コード内の単純で明らかな誤りを見つけることを目的としています。一方、デバッグフェーズは、所定のコード検査で見過ごされるより見つけにくいエラーを明らかにする際に役に立ちます。

5.1. ELF の実行可能バイナリー

Red Hat Enterprise Linux は、実行可能バイナリー、共有ライブラリーまたは debuginfo ファイルに ELF を使用し、これらの debuginfo ELF ファイル内では DWARF フォーマットが使用されます。DWARF のバージョン 3 が ELF ファイルで使用されます (gcc -ggcc -gdwarf-3 と同等)。DWARF debuginfo には以下が含まれます。
  • バイナリーのターゲットアドレスを含む、コンパイルされた関数および変数すべての名前
  • ソース行番号を含む、コンパイルに使用されるソースファイル
  • ローカル変数の場所

重要

STABS はたまに UNIX で使用されますが、より古く、機能性に乏しいフォーマットです。Red Hat ではこの使用を奨励していません。GCC および GDB での STABS の作成と使用のサポートは可能な範囲でのみ行なわれます。
これらの ELF ファイルでは、GCC debuginfo のレベルも使用されます。デフォルトはレベル 2 であり、ここではマクロ情報が表示されません。レベル 3 には C/C++ マクロ定義が含まれますが、この設定ではデバッグ情報が非常に大きくなる可能性があります。デフォルト gcc -g のコマンドは gcc -g2 と同一です。マクロ情報をレベル 3 に変更するには、gcc -g3 を使用します。
利用可能な debuginfo のレベルは複数あります。ファイルでどのセクションが使用されているかを確認するには、コマンド readelf -WS file を使用します。

表5.1 debuginfo のレベル

バイナリーの状態
コマンド
注意事項
Stripped (削除)
strip file
または
gcc -s -o file
共有ライブラリーとのランタイムリンクに必要なシンボルのみが表示されます。
使用される ELF セクション: .dynsym
ELF シンボル
gcc -o file
関数および変数の名前のみが表示され、ソースファイルのバインディングおよびタイプはありません。
使用される ELF セクション: .symtab
DWARF debuginfo (マクロあり)
gcc -g -o file
タイプも含め、ソースファイル名および行番号は認識されます。
使用される ELF セクション: .debug_*
DWARF debuginfo (マクロあり)
gcc -g3 -o file
gcc -g と似ていますが、マクロが GDB に認識されます。
使用される ELF セクション: .debug_macro

注記

GDB はソースファイルを解釈することはなく、テキストとしてそれらを表示するのみです。情報を DWARF に保存するには gcc -g とその変数を使用します。
gcc -rdynamic を使用してプログラムやライブラリーをコンパイルすることは奨励されません。特定のシンボルについては、gcc -Wl, --dynamic-list=... を代わりに使用してください。gcc -rdynamic が使用される場合、strip コマンドや -s gcc オプションの効果は一切ありません。それは、共有ライブラリーとのランタイムリンケージについてのすべての ELF シンボルがバイナリーで保持されるためです。
ELF シンボルは、readelf -s file コマンドによって読み取られます。
DWARF シンボルは、readelf -w file コマンドによって読み取られます。
コマンド readelf -wi file は、プログラム内でコンパイルされた debuginfo の優れた検証コマンドです。コマンド strip file または gcc -s は、プログラムのコンパイルのさまざまなステージの出力で誤って実行されます。
readelf -w file コマンドは、フォーマットを持つ .eh_frame と呼ばれる特殊セクションを表示するために使用でき、その目的は DWARF セクションの .debug_frame と類似しています。.eh_frame セクションは、ランタイム C++ 例外の解決に使用され、-g gcc オプションが使用されない場合であっても存在します。これはプライマリ RPM に保存され、debuginfo RPM には存在しません。
Debuginfo RPM には、.symtab および .debug_* セクションが含まれます。.eh_frame.eh_frame_hdr、または .dynsym のいずれのセクションもプログラムのランタイム時に必要になるため、debuginfo RPM には移行されず、またこの中には存在しません。