2008-09-18 3 views

Antwort

53

-g weist den Compiler an, Symboltabelleninformationen in der ausführbaren Datei zu speichern. Unter anderem beinhaltet dies:

  • Symbolnamen
  • Typ-Info für Symbole
  • Dateien und Zeilennummern, wobei die Symbole von
  • kam

Debuggers verwenden diese Informationen zur Ausgabe aussagekräftige Namen für Symbole und um Anweisungen bestimmten Zeilen in der Quelle zuzuordnen.

Bei einigen Compilern werden durch die Angabe von -g bestimmte Optimierungen deaktiviert. Zum Beispiel setzt icc die Standard-Optimierungsebene auf -0 mit -g, es sei denn, Sie geben explizit -O [123] an. Auch wenn Sie -O [123] angeben, werden Optimierungen, die das Stack-Tracing verhindern, weiterhin deaktiviert (z. B. Entfernen von Frame-Zeigern aus Stack-Frames. Dies wirkt sich nur geringfügig auf die Leistung aus).

Mit einigen Compilern deaktiviert -g Optimierungen, die verwechseln können, woher die Symbole kamen (Neuanordnen von Anweisungen, Loop-Abrollung, Inlining usw.). Wenn Sie mit der Optimierung debuggen möchten, können Sie -g3 mit gcc verwenden, um etwas davon zu umgehen. Zusätzliche Debug-Informationen werden über Makros, Erweiterungen und Funktionen, die möglicherweise inlined wurden, eingefügt. Dies ermöglicht es Debuggern und Leistungstools, optimierten Code der ursprünglichen Quelle zuzuordnen, aber es ist der beste Aufwand. Einige Optimierungen beeinträchtigen den Code wirklich.

Weitere Informationen finden Sie unter DWARF, dem Debugging-Format, das ursprünglich für ELF (das Binärformat für Linux und andere Betriebssysteme) entwickelt wurde.

+1

Nur um das hinzuzufügen, kann es auch die ausführbare Datei verlangsamen. Ich habe mit dem Sun Studio-Compiler einen OpenMP-Code getestet, und mit Debugging-Informationen lief der Code viel langsamer. Nur etwas zu beachten. – Mike

+4

Wenn die Option -g im Sun-Compiler bestimmte Optimierungen nicht deaktiviert, sollten Debug-Informationen den Code NICHT verlangsamen. – tgamblin

+0

Dies ist OpenMP-Code, und es hat es verlangsamt. Ich spielte mit Fraktalen und arbeitete an den OpenMP-Compiler-Erweiterungen. Der Code in einem einzelnen Thread lief langsamer als der Nicht-OpenMP-Code in einem einzelnen Thread. Ich habe das Debugging deaktiviert und die Geschwindigkeit ausgeglichen. – Mike

7

Der ausführbaren Datei wird eine Symboltabelle hinzugefügt, die Funktions-/Variablennamen den Datenspeicherorten zuordnet, sodass Debugger wichtige Informationen und nicht nur Zeiger zurückmelden können. Dies wirkt sich nicht auf die Geschwindigkeit Ihres Programms aus und Sie können die Symboltabelle mit dem Befehl 'strip' entfernen.

3

Es gibt einige Überschneidungen mit dieser question, die das Problem von der anderen Seite abdeckt.

3

Nur als eine Frage von Interesse, können Sie öffnen Sie einen Hexeditor und betrachten Sie eine ausführbare Datei mit -g und eine ohne. Sie können die Symbole und Dinge sehen, die hinzugefügt werden. Es kann auch die Baugruppe ändern (-S), aber ich bin mir nicht sicher.

6

-g fügt Debuginformationen in die ausführbare Datei ein, z. B. die Namen von Variablen, die Namen von Funktionen und Zeilennummern. Dies ermöglicht einem Debugger, z. B. gdb, Code Zeile für Zeile durchzugehen, Haltepunkte festzulegen und die Werte von Variablen zu überprüfen. Aus diesem Grund erhöht die Verwendung von -g die Größe der ausführbaren Datei.

Außerdem ermöglicht gcc die Verwendung von -g zusammen mit -O-Flags, die die Optimierung einschalten. Das Debuggen einer optimierten ausführbaren Datei kann sehr schwierig sein, da Variablen weg optimiert werden können oder Anweisungen in einer anderen Reihenfolge ausgeführt werden können. Im Allgemeinen ist es eine gute Idee, die Optimierung auszuschalten, wenn Sie -g verwenden, obwohl dies zu viel langsameren Code führt.

8

Zusätzlich zum Debuggen und Symbolinformationen
Google ZWERG (A Entwickler Witz auf ELF)

Durch die meisten Compiler-Optimierungen Standard werden ausgeschaltet, wenn aktiviert ist Debuggen.
Der Code ist also die reine Übersetzung der Quelle in Maschinencode und nicht das Ergebnis vieler hochspezialisierter Transformationen, die auf die Freigabe von Binärdateien angewendet werden. Der wichtigste Unterschied (meiner Meinung nach)
Speicher in Debug-Builds wird in der Regel zu einigen Compiler-spezifischen Werten initialisiert, um das Debuggen zu erleichtern. In Release-Builds wird Speicher nicht initialisiert, es sei denn, dies wird explizit vom Anwendungscode ausgeführt.

Überprüfen Sie die Compiler-Dokumentation Weitere Informationen:
Aber ein Beispiel für DevStudio ist:

  • 0xCDCDCDCD in Heap, aber nicht
  • 0xDDDDDDDD freigegeben Heap-Speicher initialisiert.
  • 0xFDFDFDFD "NoMansLand" Zäune automatisch an der Grenze des Heap-Speichers platziert. Sollte niemals überschrieben werden. Wenn Sie einen überschreiben, gehen Sie wahrscheinlich über das Ende eines Arrays hinaus.
  • 0xCCCCCCCC auf Stapel reserviert, aber nicht
3

Einige Betriebssysteme initialisiert (wie z/OS) erzeugen eine „Seite-Datei“, die die Debug-Symbole enthält. Dies hilft zu vermeiden, die ausführbare Datei mit zusätzlichen Informationen aufzublähen.

Verwandte Themen