Ejemplo
int *ptr;
*ptr = 1000;
kann ich mit Standard-C++ eine Ausnahme von der Speicherzugriffsverletzung abfangen, ohne dass ich eine microsoft-spezifische.
Ejemplo
int *ptr;
*ptr = 1000;
kann ich mit Standard-C++ eine Ausnahme von der Speicherzugriffsverletzung abfangen, ohne dass ich eine microsoft-spezifische.
Lesen Sie es und weinen Sie!
Ich habe es herausgefunden. Wenn Sie nicht aus dem Handler werfen, wird der Handler einfach weiter und so wird die Ausnahme.
Die Magie geschieht, wenn Sie Ihre eigene Ausnahme auslösen und diese behandeln.
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <tchar.h>
void SignalHandler(int signal)
{
printf("Signal %d",signal);
throw "!Access Violation!";
}
int main()
{
typedef void (*SignalHandlerPointer)(int);
SignalHandlerPointer previousHandler;
previousHandler = signal(SIGSEGV , SignalHandler);
try{
*(int *) 0 = 0;// Baaaaaaad thing that should never be caught. You should write good code in the first place.
}
catch(char *e)
{
printf("Exception Caught: %s\n",e);
}
printf("Now we continue, unhindered, like the abomination never happened. (I am an EVIL genius)\n");
printf("But please kids, DONT TRY THIS AT HOME ;)\n");
}
Es gibt eine sehr einfache Möglichkeit, jede Art von Ausnahme (Division durch Null, Zugriffsverletzung usw.) in Visual Studio mit try -> catch (...) Block. Eine kleine Änderung der Projekteinstellungen ist ausreichend. Aktivieren Sie einfach die Option /EHa in den Projekteinstellungen. Siehe Projekteigenschaften -> C/C++ -> Codegenerierung -> Ändern Sie die Option C++-Ausnahmen aktivieren auf "Ja mit SEH-Ausnahmen". . Das war's!
Einzelheiten finden Sie hier: https://docs.microsoft.com/en-us/cpp/cpp/structured-exception-handling-c-cpp?view=msvc-160
Zumindest für mich ist die signal(SIGSEGV ...)
in einer anderen Antwort erwähnter Ansatz funktionierte nicht auf Win32 mit Visual C++ 2015 . Was hat Arbeit für mich war die Verwendung von _set_se_translator()
gefunden in eh.h
. Das funktioniert folgendermaßen:
Schritt 1 ) Stellen Sie sicher, dass Sie die Ja mit SEH-Ausnahmen (/EHa) en Projekteigenschaften / C++ / Codegenerierung / C++-Ausnahmen aktivieren wie in der Antwort von Wolodymyr Frytskyy .
Schritt 2 ) Aufruf _set_se_translator()
mit der Übergabe eines Funktionszeigers (oder Lambdas) für die neue Ausnahme Übersetzer . Es wird als Übersetzer bezeichnet, weil es im Grunde nur die Low-Level-Ausnahme nimmt und sie in etwas leichter Abfangbares umwandelt, z. B. in std::exception
:
#include <string>
#include <eh.h>
// Be sure to enable "Yes with SEH Exceptions (/EHa)" in C++ / Code Generation;
_set_se_translator([](unsigned int u, EXCEPTION_POINTERS *pExp) {
std::string error = "SE Exception: ";
switch (u) {
case 0xC0000005:
error += "Access Violation";
break;
default:
char result[11];
sprintf_s(result, 11, "0x%08X", u);
error += result;
};
throw std::exception(error.c_str());
});
Schritt 3 ) Fangen Sie die Ausnahme wie gewohnt ab:
try{
MakeAnException();
}
catch(std::exception ex){
HandleIt();
};
Diese Art von Situation hängt von der Implementierung ab und erfordert daher einen herstellerspezifischen Mechanismus, um eine Falle zu stellen. Bei Microsoft ist dies SEH, bei *nix ist es ein Signal
Im Allgemeinen ist das Abfangen einer Access Violation Exception jedoch eine sehr schlechte Idee. Es gibt fast keine Möglichkeit, sich von einer AV-Ausnahme zu erholen, und der Versuch, dies zu tun, führt nur zu schwer zu findenden Fehlern in Ihrem Programm.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.