Mit gdb können Sie Ausnahmen abfangen, wenn sie ausgelöst werden und wenn sie abgefangen werden. Aber manchmal hat die Zeile, für die eine Ausnahme ausgelöst wird, keine Symbole, oder während der Ausnahmebehandlung wird ein Haltepunkt ausgelöst. Wie überprüfe ich den Wert der aktuellen Ausnahme?Wie bekomme ich den Wert und den Typ der aktuellen Ausnahme in C++ mit gdb?
Antwort
Aktualisiert
Hier einige Informationen aus der GDB-Handbuch
Es liegen noch einige Einschränkungen C++ Ausnahmebehandlung (Fang Wurf und Beifang) in GDB:
Wenn Sie eine Funktion interaktiv aufrufen, gibt gdb normalerweise die Kontrolle an Sie zurück, wenn die Funktion hat fertig ausgeführt. Wenn der Aufruf eine Ausnahme auslöst, kann der Aufruf jedoch den Mechanismus umgehen, der Steuerung an Sie zurückgibt und Ihr Programm entweder abbrechen oder fortsetzen, bis es einen Haltepunkt erreicht, ein Signal abfängt, das gdb wartet oder beendet. Dies ist auch dann der Fall, wenn Sie für die Ausnahme einen Catchpoint setzen; Zwischenrufe bei Ausnahmen sind in interaktiven Anrufen deaktiviert. Sie können eine Ausnahme nicht interaktiv auslösen. Sie können einen Ausnahmehandler nicht interaktiv installieren. Manchmal catch ist nicht der beste Weg, um die Ausnahmebehandlung zu debuggen: wenn Sie wissen müssen genau, wo eine Ausnahme ausgelöst wird, ist es besser zu stoppen, bevor die Ausnahmeroutine aufgerufen wird, da auf diese Weise Sie den Stapel vor jedem sehen können die Abwicklung findet statt. Wenn Sie stattdessen einen Haltepunkt in einem Exception-Handler festlegen, ist es möglicherweise nicht einfach herauszufinden, wo die Ausnahme ausgelöst wurde.
Um kurz vor dem Aufruf eines Exception-Handlers zu stoppen, benötigen Sie einige Kenntnisse der Implementierung. Im Fall von Gnu C++, Ausnahmen durch den Aufruf einer Bibliotheksfunktion namens __raise_exception angehoben werden, die die folgenden ANSI-C-Schnittstelle:
/* addr is where the exception identifier is stored. id is the exception identifier. */ void __raise_exception (void **addr, void *id); To make the debugger catch all exceptions before any stack unwinding takes place,
einen Haltepunkt auf __raise_exception (siehe Haltepunkte, Beobachtungspunkte; und Ausnahmen).
Das heißt
Es hängt von der Code und wo Sie in dem Stapel sind. Wenn Sie tatsächlich die Ausnahme wie in gefangen:
try { .... } catch (std::exception &e) {
//do stuff
}
könnten Sie versuchen, wahrscheinlich e.what()
Druck oder bei den Mitgliedern der Ausnahme betrachten. Wenn Sie es gerade als (...) gefangen haben, dann bin ich mir nicht sicher, was Sie sammeln könnten.
Eine andere Sache, die Sie tun können, ist 'werfen' in gdb und fangen 'fangen' auch, wenn Sie wirklich den ganzen Fluss folgen wollen.
gdb> catch catch
gdb> catch throw
Auf diese Weise werden Sie einen Haltepunkt richtig machen, bevor Ausnahmen geworfen werden und richtig, da sie gefangen sind, können Sie dann den Stapel gehen mehr Informationen darüber zu gewinnen, was los war. Selbst wenn Sie sich in einem anderen Haltepunkt befinden, sollten Sie in der Lage sein, den Stapel zu durchlaufen (mit den Pfeiltasten nach oben oder nach unten), um den Rahmen zu erhalten, in dem die Ausnahme sichtbar ist.
Kurze Antwort: Sie können nicht, weil die meiste Arbeit der Ausnahmebehandlung außerhalb Ihres Programms getan wird, und deshalb außerhalb des Umfangs von gdb ist.
Erklärung der Antwort:
manchmal die Linie eine Ausnahme ausgelöst hat keine Symbole
Wenn die binäre Sie Debuggen keine Debug-Symbole hat dann die binäre wahrscheinlich abgestreift wird und Sie gewonnen‘ Ich kann überhaupt nicht viel über die Arten/Werte von irgendetwas herausfinden.
Wie überprüfe ich den Wert der aktuellen Ausnahme?
Ich denke, Sie gehen hier davon aus, dass eine Ausnahme eine Sprachfunktion ist, die gdb inspizieren kann; Eine Ausnahme in C++ ist eine Kombination von Features aus C++ als Sprache, aus libC++ und dem ABI. Und es könnte sogar mehr als eine einzige aktive Ausnahme geben. Wie UpAndAdam darauf hinweist, können Sie einen Haltepunkt in einem Fangblock mit einem Typspezifizierer festlegen und dann dieses Element untersuchen, aber ich vermute, dass Ihr Problem in Fällen liegt, in denen Sie ein "catch (...)" finden. In diesen Fällen können Sie nicht viel über die aktuelle Ausnahme erfahren, es sei denn, Sie befassen sich mit der Implementierung der Ausnahmebehandlung.
Bei einer sehr kurzen und unvollständigen Beschreibung wir, dass eine Ausnahme werfen könnten sagen:
- Ihr Programm ruft ++ libc eine Ausnahme
- zu erhöhen libC++ rufen „entspannen“ in glibc den Stapel zu starten Abwickeln
- Abwickelstation wird eine „Persönlichkeit Funktion“ von libC++ für jeden Stapelrahmen (jeder Funktionsaufruf in dem Stapel, im Allgemeinen)
- die Persönlichkeit funktionieren kann, wenn der aktuelle Stapelrahmen irgendwie entscheiden Rückruf oder diese nicht verarbeiten kann Ausnahme
- , wenn die Ausnahme kann der Block catch behandelt werden
nun ausgeführt werden, ist es schwierig, über Details zu sprechen, weil viele Ausnahmebehandlung auf Ihrem Werkzeugkette hängt (Compiler, Plattform, Architektur, libC++, etc.) aber in den meisten Fällen wird ein "catch (...)" nicht einmal die ursprüngliche Ausnahme als Argument erhalten. Auf jeden Fall beantworten irgendwie Ihre Frage: in gcc mit GNUs libC++ Sie so etwas wie dies versuchen könnte:
- Holen Sie sich ein libC++ mit Bugsymbol
- einen Haltepunkt in __gxx_personality_v0 Set (das die Persönlichkeit Funktion genannt).Diese Funktion wird aufgerufen, um zu bestimmen, ob ein Stapelrahmen (im Prinzip ein Funktionsaufruf) über einen geeigneten catch-Block verfügt, um die Ausnahme zu behandeln
- In der Personality-Funktion können Sie einen Zeiger auf _Unwind_Exception finden, der ein Wrapper ist zu Ihrer echten Ausnahme
- Erhalten Sie die Typinfo für Ihre Ausnahme wie folgt: __cxa_exception * exception_header = (__cxa_exception *) (abwicklung_exception + 1) -1; std :: type_info * geworfene_exception_type = exception_header-> exceptionType;
- Sie erhalten eine Ausnahme-Typ erhalten, die Sie dann mit dem Rest des RTTI definiert für Ihren Code
In jedem Fall Nachschlag kann, müssen Sie wahrscheinlich versuchen, ziemlich viel Zeit damit verbringen, zu verstehen, wie die Ausnahmebehandlung in Ihrer Plattform implementiert ist. Wenn Sie etwas mehr über die Ausnahmebehandlung lesen möchten, habe ich in der Vergangenheit etwas über das Thema @http://monoinfinito.wordpress.com/series/exception-handling-in-c/ geschrieben. Es ist keine offizielle Quelle, aber es enthält Links zu den Spezifikationen jedes Teils, der an der Behandlung einer Ausnahme beteiligt ist.
Diese Antworten waren korrekt, wenn sie geschrieben wurden, aber seither haben sich gdb und libstdC++ geändert.
libstdC++ hat jetzt einige Hooks, die gdb besser mit dem Ausnahmesystem interagieren lassen. Insbesondere gibt es nun genügend Informationen für gdb, um dem Benutzer eine $_exception
Convenience-Variable bereitzustellen. Diese Variable enthält die Ausnahme, die ausgelöst wird. Es ist nur an genau der Stelle gültig, an der die Ausnahme abgefangen wird; mit dem Sie aufhören können, catch catch
zu verwenden.
Weitere Informationen finden Sie unter the page from the manual.
- 1. Wie bekomme ich den Typ der Ausnahme in C#
- 2. CABasicAnimation Wie bekomme ich den aktuellen Drehwinkel
- 3. Wie bekomme ich den aktuellen Zeitstempel in C++ seit 1970?
- 4. Wie bekomme ich den aktuellen Wert vom ReactiveCooco Signal?
- 5. Wie kann ich auf den Typ der aktuellen Klasse verweisen?
- 6. Wie lese ich den Wert aller Register mit gdb?
- 7. Wie bekomme ich den aktuellen Zustand der Feststelltaste in VB.NET?
- 8. Wie bekomme ich den aktuellen TimeStamp?
- 9. Wie bekomme ich den aktuellen Tag der Woche in vimscript?
- 10. Wie bekomme ich den Speicherort der aktuellen Datei in Revel
- 11. Wie bekomme ich den Namen der aktuellen Funktion?
- 12. Wie bekomme ich den aktuellen Benutzer mit jsonwebtoken in Sails.js?
- 13. Wie bekomme ich den aktuellen pk, auf den zugegriffen wird?
- 14. Wie kann ich einen Wert von boost :: any sehen, wenn ich den Typ mit gdb kenne
- 15. Wie bekomme ich den Wert einer anderen Variablen in C#
- 16. C# erneut eine Ausnahme auslösen: Wie bekomme ich den Ausnahme-Stack in der IDE?
- 17. Wie bekomme ich den Verzeichnisnamen von Inode-Wert in c?
- 18. Wie bekomme ich den Wert der nächsten Iteration in der aktuellen Iteration
- 19. Wie bekomme ich den aktuellen Hostnamen in Heroku?
- 20. Wie bekomme ich den Wert des Kontrollkästchens deaktiviert in C#
- 21. Wie bekomme ich den aktuellen Zeilenindex meiner Tabelle mit Jquery?
- 22. Sublime text: Wie bekomme ich den Dateinamen der aktuellen Ansicht
- 23. Wie bekomme ich den Typ dieses Objekts?
- 24. SQL: Wie bekomme ich den Sonntag der aktuellen Woche
- 25. Angular2 bekomme den Aliasnamen der aktuellen Route
- 26. Wie bekomme ich den Teilstring in C#?
- 27. Wie bekomme ich den Combobox-Wert?
- 28. Wie bekomme ich den aktuellen/aktiven Zweig mit LibGit2Sharp?
- 29. Wie bekomme ich den Wert von @DiscriminatorColumn()?
- 30. Wie bekomme ich den Wert von Spinner