デバッグ オプション -g はバイナリ実行可能ファイルをどのように変更しますか?

StackOverflow https://stackoverflow.com/questions/89603

  •  01-07-2019
  •  | 
  •  

質問

C/C++ コードを作成する場合、バイナリ実行可能ファイルをデバッグするには、コンパイラ/リンカーでデバッグ オプションを有効にする必要があります。GCC の場合、オプションは -g です。デバッグ オプションが有効になっている場合、バイナリ実行可能ファイルにどのような影響がありますか?デバッガ機能をそのまま使用できるようにするファイルには、どのような追加データが保存されていますか?

役に立ちましたか?

解決

-g は、シンボル テーブル情報を実行可能ファイルに保存するようにコンパイラーに指示します。これには特に次のものが含まれます。

  • シンボル名
  • シンボルの型情報
  • シンボルの由来となったファイルと行番号

デバッガはこの情報を使用して、シンボルの意味のある名前を出力し、命令をソース内の特定の行に関連付けます。

一部のコンパイラでは、-g を指定すると特定の最適化が無効になります。たとえば、明示的に -O[123] を指定しない限り、icc は -g を指定するとデフォルトの最適化レベルを -O0 に設定します。また、-O[123] を指定した場合でも、スタック トレースを妨げる最適化は無効のままです (例:スタックフレームからフレームポインタを削除します。これによるパフォーマンスへの影響はわずかです)。

一部のコンパイラでは、-g を指定すると、シンボルの出所を混乱させる可能性のある最適化 (命令の並べ替え、ループの展開、インライン化など) が無効になります。最適化してデバッグしたい場合は、gcc で -g3 を使用すると、この問題の一部を回避できます。インライン化された可能性のあるマクロ、拡張、関数に関する追加のデバッグ情報が含まれます。これにより、デバッガーやパフォーマンス ツールで最適化されたコードを元のソースにマップできるようになりますが、これはベストエフォートです。最適化によっては、実際にコードが破損してしまう場合があります。

詳細については、こちらをご覧ください。 ドワーフ, 、元々は ELF (Linux およびその他の OS のバイナリ形式) に合わせて設計されたデバッグ形式です。

他のヒント

関数/変数名をデータの場所にマップするシンボル テーブルが実行可能ファイルに追加されるため、デバッガーは単なるポインターではなく意味のある情報をレポートできます。これはプログラムの速度には影響せず、「strip」コマンドを使用してシンボル テーブルを削除できます。

デバッグ情報やシンボル情報に加えて
Google DWARF (ELF に関する開発者のジョーク)

デフォルトでは、デバッグが有効な場合、ほとんどのコンパイラの最適化はオフになります。
したがって、コードは、バイナリをリリースするために適用される多くの高度に特殊な変換の結果ではなく、ソースをマシン コードに純粋に変換したものです。

しかし、最も重要な違いは(私の意見では)
デバッグ ビルドのメモリは通常、デバッグを容易にするためにコンパイラ固有の値に初期化されます。リリース ビルドでは、アプリケーション コードによって明示的に行われない限り、メモリは初期化されません。

詳細については、コンパイラのドキュメントを確認してください。
ただし、DevStudio の例は次のとおりです。

  • 0xCDCDCDCD ヒープに割り当てられていますが、初期化されていません
  • 0xDDDDDDDD ヒープ メモリを解放しました。
  • 0xFDFDFDFD 「NoMansLand」フェンスはヒープ メモリの境界に自動的に配置されます。決して上書きしないでください。上書きすると、おそらく配列の末尾から外れてしまうことになります。
  • 0xCCCCCCCC スタックに割り当てられていますが、初期化されていません

-g は、変数名、関数名、行番号などのデバッグ情報を実行可能ファイルに追加します。これにより、gdb などのデバッガがコードを 1 行ずつステップ実行し、ブレークポイントを設定し、変数の値を検査できるようになります。この追加情報のため、-g を使用すると実行可能ファイルのサイズが増加します。

また、gcc では、最適化を有効にする -g を -O フラグと一緒に使用できます。変数が最適化されて削除されたり、命令が異なる順序で実行されたりする可能性があるため、最適化された実行可能ファイルのデバッグは非常に難しい場合があります。一般に、-g を使用する場合は、コードが大幅に遅くなる場合でも、最適化をオフにすることをお勧めします。

これと重なる部分もある 質問 この問題を反対側からカバーします。

興味深いことに、ヘキエディタを開いて、次のコマンドで生成された実行可能ファイルを見てみることができます。 -g そしてなしのもの。追加された記号などを確認できます。アセンブリが変更される可能性があります (-S)もそうですが、よくわかりません。

一部のオペレーティング システム ( z/OS) デバッグ シンボルを含む「サイド ファイル」を生成します。これにより、実行可能ファイルが余分な情報で肥大化するのを避けることができます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top