Was genau passiert beim Kompilieren mit -funwind-tables?

Lesezeit: 4 Minuten

Benutzer-Avatar
Pendyala

Aus: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html

-fexceptions: Ausnahmebehandlung aktivieren. Generiert zusätzlichen Code, der zum Weitergeben von Ausnahmen erforderlich ist. Für einige Ziele bedeutet dies, dass GCC Frame-Unwind-Informationen für alle Funktionen generiert,

-funwind-tables Ähnlich zu -fexceptions, außer dass es nur alle erforderlichen statischen Daten generiert, aber den generierten Code in keiner anderen Weise beeinflusst. Normalerweise müssen Sie diese Option nicht aktivieren; Stattdessen aktiviert ein Sprachprozessor, der diese Handhabung benötigt, sie in Ihrem Namen.

Könnte jemand bitte erklären, von -funwind-tables, was bedeutet es mit “alle erforderlichen statischen Daten”. Auf welche Daten sie sich beziehen. Und warum müssen die Daten generiert werden? Was passiert, wenn diese Daten nicht generiert werden? Wofür werden diese Daten verwendet?

Und da steht auch “ähnlich -fexception“. Ich denke also, dass es auch Frame-Unwind-Informationen generiert. Was sind Frame-Unwind-Informationen? Wer verwendet die Frame-Informationen und wie?

In einigen SO-Beiträgen habe ich gelesen, dass Programme mit diesem Flag für die kompiliert werden müssen _Unwind_Backtrace muss richtig funktionieren. Bitte erklären Sie, wie _Unwind_Backtrace Verwenden Sie die Informationen, die von generiert wurden -funwind-tables.

  • Dieses Video über Ausnahmen könnte Ihnen gefallen. Es ist für MSVC, aber es gibt Ihnen einige Einblicke. GCC verwendet wahrscheinlich ähnliche Techniken. youtube.com/watch?v=COEv2kq_Ht8

    – engf-010

    1. November 2018 um 13:53 Uhr

  • Dies kann Ihnen einen Anfang geben: itanium-cxx-abi.github.io/cxx-abi/exceptions.pdf

    – Johannes Zwinck

    1. November 2018 um 14:27 Uhr

  • @engf-010, danke, dieser Link gibt wirklich viele Einblicke in das Thema. empfehle jedem, der Fragen wie ich hat, sich das anzuhören. Naive wie ich, müssen ein paar Mal zuschauen 🙂

    – Pendyala

    3. November 2018 um 17:36 Uhr

Die genannten statischen Daten für die -funwind-tables Option sind die Frame-Abwicklungsinformationen, dh Daten, die es einem laufenden Programm ermöglichen, die Funktionsaufrufliste von einem bestimmten Ausführungspunkt zurückzugehen. Den Funktionsaufrufstapel zurückzugehen bedeutet, vom Ausführungskontext einer aufgerufenen Funktion zum Kontext des Aufrufers zu wechseln, dh was normalerweise passiert, wenn Sie Rückkehr aus einer Funktion, mit der Ausnahme, dass Frame-Unwind-Informationen es Ihnen ermöglichen, dies von einem beliebigen Punkt innerhalb des Hauptteils einer Funktion aus zu tun; Sie sind auch nicht gezwungen, die aufgerufene Funktion tatsächlich zu beenden, Sie könnten einfach in den Kontext des Aufrufers “einsehen” (z. B. um den Ort abzurufen, von dem die aufgerufene Funktion aufgerufen wurde), auch rekursiv, aber dann den normalen Ausführungsablauf in fortsetzen genannte Funktion.

Um dies tun zu können, müssen Sie Zugriff auf mehr Informationen über den kompilierten Code haben, als unbedingt erforderlich sind, damit ein Programm einem “normalen” Ausführungsablauf folgt. Diese Informationen (dh die Frame-Unwind-Informationen) werden vom Linker in speziellen Linker-Abschnitten (z. B. dem Abschnitt .eh_frame für die x86-Plattform oder den Abschnitten ARM.exidx und .ARM.extab für die ARM-Plattform) abgelegt, die für diesen Zweck bestimmt sind; Diese Linker-Abschnitte sind die gleichen, die in Sprachen wie C++ benötigt werden, um eine Ausnahmebehandlung zu implementieren, bei der der Ausführungsfluss als Ergebnis einer ausgelösten Ausnahme von einer aufgerufenen Funktion zu ihrem Aufrufer springen könnte. Wenn Sie die Generierung dieser Daten deaktivieren, indem Sie die -fno-unwind-tables -Option können Sie den Funktionsaufruf-Stack nicht zurückgehen oder C++-Ausnahmen verwenden.

Insbesondere werden Frame-Unwind-Informationen von verwendet Libunwindeine plattformübergreifende Bibliothek, die das Generieren von Backtraces, das Springen zu beliebigen Punkten in der Aufrufliste und mehr unterstützt.

_Unwind_Backtrace() ist eine in den GCC-Kernbibliotheken (genauer in libgcc_s) implementierte Funktion, die es ermöglicht, eine Callback-Funktion (als Argument geliefert) für jeden Frame im Call-Stack auszuführen, d. h. ausgehend vom Kontext der aufrufenden Funktion, die Bewegung zu ihrem Aufrufer, usw. Sehen https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/baselib–unwind-backtrace.html. Auch hier muss diese Funktion, um ihre Aufgaben erledigen zu können, auf die Frame-Abwicklungsinformationen aus den entsprechenden Linker-Abschnitten zugreifen.

  • Danke Francesco für die Informationen. Gibt es eine Möglichkeit zu überprüfen, ob in den Abschnitten .eh_frame(x86) oder ARM.exidx und ARM.extab(arm) Informationen zum Entladen vorhanden sind. Gibt es eine bestimmte Zeichenfolge, die bestätigt, dass solche Abwicklungsinformationen tatsächlich vorhanden sind?

    – Pendyala

    2. November 2018 um 12:43 Uhr


  • Ich weiß nicht viel über das Datenformat, das in diesen Linker-Abschnitten verwendet wird, aber für die ARM-Plattform können Sie das readelf-Dienstprogramm mit dem verwenden -u Befehlszeilenoption zum Anzeigen der Entladetabellen: Wenn eine Datei mit Entladeinformationen erstellt wurde, zeigt readelf diese Informationen für jede Funktion im Code an. Das -u Die Option unterstützt jedoch keine Frame-Unwind-Informationen für x86.

    – Francesco Lawra

    2. November 2018 um 15:32 Uhr


  • Danke für die fantastische Antwort!

    – Andrés Mejía

    2. August 2019 um 20:23 Uhr

1333980cookie-checkWas genau passiert beim Kompilieren mit -funwind-tables?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy