Ich würde gerne wissen, wie GCC die Ausnahmebehandlung für C ++ - Programme implementiert. Ich konnte keinen leicht verständlichen und selbsterklärenden Artikel im Web finden (obwohl es viele solcher Artikel für Visual C ++ gibt). Ich weiß nur, dass die Implementierung von GCC DWARF-Ausnahmebehandlung heißt.
Ich habe ein kleines C ++ - Programm geschrieben und es mit dem Befehl in die Assembly übersetzt:
g ++ main.cpp -S -Masm = intel -fno-dwarf2-cfi-asm
Die Dateien main.cpp und main.s werden hier angegeben. Könnte jemand bitte den Inhalt der main.s-Datei erklären, insbesondere die Abschnitte .gcc_except_table
und .eh_frame
Zeile für Zeile? (Mein Betriebssystem ist Ubuntu 13.04 32-Bit.) Danke!
main.cpp:
%Vor%main.s:
%Vor% .eh_frame
layout wird kurz in der LSB-Dokumentation beschrieben . Ian Lance Taylor (Autor des Gold-Linkers) hat auch einige Blogposts auf .eh_frame
und %Co_de% Layout .
Für eine mehr Referenz-ähnliche Beschreibung, überprüfen Sie meine Recon 2012 Slides (Beginn um 37 oder so).
BEARBEITEN : Hier sind die kommentierten Strukturen aus Ihrem Beispiel. Zuerst die .gcc_except_table
(einige Teile wurden der Übersichtlichkeit halber weggelassen):
Als nächstes folgt der LSDA (sprachspezifischer Datenbereich), auf den von FDE 3 verwiesen wird:
%Vor%Der Itanium-ABI (dem sowohl gcc, clang als auch eine Reihe anderer folgen) legt fest, dass die Ausnahmebehandlung dem Null-Kosten-Strategie .
Die Idee der Zero-Cost-Strategie besteht darin, die gesamte Ausnahmebehandlung in Seitentabellen zu pushen, die nicht im Hauptprogrammausführungspfad enthalten sind (und somit den Anweisungscache nicht löschen). Diese Tabellen werden vom Programmpunkt indiziert.
Darüber hinaus werden DWARF-Informationen (die eigentlich Debug-Informationen sind) zum Abwickeln des Stapels verwendet. Diese Funktionalität wird normalerweise als Bibliothek zur Verfügung gestellt, wie zum Beispiel libunwind sehr plattformspezifisch).
Vorteile:
try
/ catch
block (so schnell, als ob es keine gab) throw
-Anweisung in einer Funktion (solange sie nicht belegt ist) Nachteil:
if
Strategie), weil die Seitentabellen normalerweise nicht im Cache sind und dann teure Berechnungen ausgeführt werden müssen, um zu wissen, welche catch
-Klausel tatsächlich (basierend auf RTTI) Es ist eine sehr populäre Strategie, sowohl für 32-Bit- als auch für 64-Bit-Plattformen für alle größeren Compiler zu implementieren ... außer MSVC 32 Bit (wenn ich mich richtig erinnere).
Tags und Links c++ gcc assembly exception-handling reverse-engineering