第5章 デバッグ
通常、有用で質の高いソフトウェアは、アプリケーション開発の複数フェーズを経て作成されるため、その間にミスについての十分な機会が設けられます。一部のフェーズには、エラーを検出する一連のメカニズムがそれぞれ設定されています。たとえば、変数や関数などのオブジェクトが適切に記述されていることを確認するために、コンパイル時に基本的なセマンティクス解析が行われます。
アプリケーション開発の各フェーズで実行されるエラーチェックのメカニズムは、コード内の単純で明らかな誤りを見つけることを目的としています。一方、デバッグフェーズは、所定のコード検査で見過ごされるより見つけにくいエラーを明らかにする際に役に立ちます。
5.1. ELF の実行可能バイナリー
Red Hat Enterprise Linux は、実行可能バイナリー、共有ライブラリーまたは debuginfo ファイルに ELF を使用し、これらの debuginfo ELF ファイル内では DWARF フォーマットが使用されます。DWARF のバージョン 3 が ELF ファイルで使用されます (
gcc -g
は gcc -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
を使用します。
バイナリーの状態
|
コマンド
|
注意事項
|
---|---|---|
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 には移行されず、またこの中には存在しません。