Beispiel
int *ptr;
*ptr = 1000;
Kann ich eine Ausnahme von Speicherzugriffsverletzungen mit Standard-C ++ abfangen, ohne Microsoft-spezifisch zu verwenden?
c++
exception-handling
Ahmed Said
quelle
quelle
Lies das und weine!
Ich habe es herausgefunden. Wenn Sie nicht vom Handler werfen, fährt der Handler einfach fort, ebenso wie die Ausnahme.
Die Magie passiert, wenn Sie Ihre eigene Ausnahme auslösen und damit umgehen.
quelle
sigaltstack
) installiert sein (es sei denn, die C ++ - Ausnahme-Abwicklungsimplementierung erlaubt dies), und jede Laufzeitfunktion, die den Abwicklungsmechanismus selbst handhabt, sollte signal-sicher sein.signal(SIGSEGV, SIG_DFL);
Es gibt eine sehr einfache Möglichkeit, jede Art von Ausnahme (Division durch Null, Zugriffsverletzung usw.) in Visual Studio mit dem Block try -> catch (...) abzufangen. Eine geringfügige Änderung der Projekteinstellungen ist ausreichend. Aktivieren Sie einfach die Option / EHa in den Projekteinstellungen. Siehe Projekteigenschaften -> C / C ++ -> Codegenerierung -> Ändern Sie die C ++ - Ausnahmen aktivieren in "Ja mit SEH-Ausnahmen" . Das ist es!
Details finden Sie hier: http://msdn.microsoft.com/en-us/library/1deeycx5(v=vs.80).aspx
quelle
Zumindest für mich funktionierte der
signal(SIGSEGV ...)
in einer anderen Antwort erwähnte Ansatz unter Win32 mit Visual C ++ 2015 nicht . Was tat Arbeit für mich war zu verwenden_set_se_translator()
gefundeneh.h
. Es funktioniert so:Schritt 1 ) Stellen Sie sicher, dass Sie Ja mit SEH-Ausnahmen (/ EHa) in Projekteigenschaften / C ++ / Codegenerierung / C ++ - Ausnahmen aktivieren aktivieren , wie in der Antwort von Volodymyr Frytskyy erwähnt .
Schritt 2 ) Aufruf
_set_se_translator()
, in einem Funktionszeiger Passing (oder Lambda) für den neuen Ausnahmesetzer . Es wird als Übersetzer bezeichnet, da es im Grunde genommen nur die Ausnahme auf niedriger Ebene nimmt und sie erneut als etwas abfängt, das leichter zu fangen ist, wie zum Beispiel :std::exception
Schritt 3 ) Fangen Sie die Ausnahme wie gewohnt ab:
quelle
Diese Art von Situation ist implementierungsabhängig und erfordert folglich einen herstellerspezifischen Mechanismus, um zu fangen. Bei Microsoft handelt es sich um SEH und bei * nix um ein Signal
Im Allgemeinen ist es jedoch eine sehr schlechte Idee , eine Ausnahme für Zugriffsverletzungen abzufangen . Es gibt fast keine Möglichkeit, sich von einer AV-Ausnahme zu erholen. Wenn Sie dies versuchen, wird es nur schwieriger, Fehler in Ihrem Programm zu finden.
quelle
Wie bereits erwähnt, gibt es auf der Windows-Plattform keine Möglichkeit, dies von Nicht-Microsoft- / Compiler-Anbietern zu tun. Es ist jedoch offensichtlich nützlich, diese Arten von Ausnahmen auf die normale try {} catch (Ausnahme ex) {} -Methode abzufangen, um Fehler zu melden und Ihre App ordnungsgemäß zu beenden (wie JaredPar sagt, ist die App jetzt wahrscheinlich in Schwierigkeiten). . Wir verwenden _se_translator_function in einem einfachen Klassen-Wrapper, mit dem wir die folgenden Ausnahmen in einem Try-Handler abfangen können:
Die ursprüngliche Klasse stammt aus diesem sehr nützlichen Artikel:
http://www.codeproject.com/KB/cpp/exception.aspx
quelle
Nicht der Ausnahmebehandlungsmechanismus, aber Sie können den signal () -Mechanismus verwenden, der vom C bereitgestellt wird.
Das Schreiben in einen NULL-Zeiger wird wahrscheinlich ein SIGSEGV-Signal verursachen
quelle
signal()
ist Teil des Posix-Standards. Windows implementiert den Posix-Standard (wie auch Linux und Unix)Eine solche Verletzung bedeutet, dass etwas ernsthaft mit dem Code nicht stimmt und unzuverlässig ist. Ich kann sehen, dass ein Programm möglicherweise versuchen möchte, die Daten des Benutzers so zu speichern, dass man hofft, dass sie nicht über vorherige Daten schreiben, in der Hoffnung, dass die Daten des Benutzers nicht bereits beschädigt sind, aber es gibt per Definition keine Standardmethode mit undefiniertem Verhalten umzugehen.
quelle