Exemple
int *ptr;
*ptr = 1000;
puis-je intercepter une exception de violation d'accès à la mémoire en utilisant C ++ standard sans utiliser de Microsoft spécifique.
c++
exception-handling
Ahmed Said
la source
la source
Lit ça et pleure!
Je l'ai compris. Si vous ne lancez pas le gestionnaire, le gestionnaire continuera simplement, tout comme l'exception.
La magie se produit lorsque vous lancez votre propre exception et gérez cela.
#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"); }
la source
sigaltstack
) ne doit être installée (à moins que l'implémentation de déroulement d'exception C ++ ne le permette), et chaque fonction d'exécution gérant le mécanisme de déroulement lui-même doit être sans danger pour le signal.signal(SIGSEGV, SIG_DFL);
Il existe un moyen très simple d'intercepter tout type d'exception (division par zéro, violation d'accès, etc.) dans Visual Studio en utilisant le bloc try -> catch (...). Une petite modification des paramètres du projet suffit. Activez simplement l'option / EHa dans les paramètres du projet. Voir Propriétés du projet -> C / C ++ -> Génération de code -> Modifiez les exceptions Activer C ++ sur "Oui avec les exceptions SEH" . C'est ça!
Voir les détails ici: http://msdn.microsoft.com/en-us/library/1deeycx5(v=vs.80).aspx
la source
Au moins pour moi, l'
signal(SIGSEGV ...)
approche mentionnée dans une autre réponse ne fonctionnait pas sur Win32 avec Visual C ++ 2015 . Ce qui a fonctionné pour moi, c'est d'utiliser_set_se_translator()
found ineh.h
. Cela fonctionne comme ceci:Étape 1 ) Assurez-vous d'activer Oui avec les exceptions SEH (/ EHa) dans Propriétés du projet / C ++ / Génération de code / Activer les exceptions C ++ , comme mentionné dans la réponse de Volodymyr Frytskyy .
Étape 2 ) Appelez
_set_se_translator()
, en passant un pointeur de fonction (ou lambda) pour le nouveau traducteur d' exceptions . Il est appelé un traducteur car il prend simplement l'exception de bas niveau et la renvoie comme quelque chose de plus facile à attraper, tel questd::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()); });
Étape 3 ) Attrapez l'exception comme vous le feriez normalement:
try{ MakeAnException(); } catch(std::exception ex){ HandleIt(); };
la source
Ce type de situation dépend de l'implémentation et par conséquent, il faudra un mécanisme spécifique au fournisseur afin de piéger. Avec Microsoft, cela impliquera SEH, et * nix impliquera un signal
En général, attraper une exception de violation d'accès est une très mauvaise idée. Il n'y a presque aucun moyen de récupérer à partir d'une exception AV et tenter de le faire conduira simplement à des bogues plus difficiles à trouver dans votre programme.
la source
Comme indiqué, il n'existe aucun moyen non Microsoft / fournisseur de compilateur de le faire sur la plate-forme Windows. Cependant, il est évidemment utile d'attraper ces types d'exceptions de la manière normale try {} catch (exception ex) {} pour signaler les erreurs et plus encore une sortie gracieuse de votre application (comme le dit JaredPar, l'application est maintenant probablement en difficulté) . Nous utilisons _se_translator_function dans un simple wrapper de classe qui nous permet d'attraper les exceptions suivantes dans un gestionnaire try:
La classe originale est issue de cet article très utile:
http://www.codeproject.com/KB/cpp/exception.aspx
la source
Pas le mécanisme de gestion des exceptions, mais vous pouvez utiliser le mécanisme signal () fourni par le C.
> man signal 11 SIGSEGV create core image segmentation violation
L'écriture sur un pointeur NULL va probablement provoquer un signal SIGSEGV
la source
signal()
fait partie du standard posix. Windows implémente le standard posix (tout comme Linux et unix)Une violation comme celle-là signifie qu'il y a quelque chose qui ne va pas dans le code et que ce n'est pas fiable. Je peux voir qu'un programme peut vouloir essayer de sauvegarder les données de l'utilisateur d'une manière que l'on espère ne pas écraser sur les données précédentes, dans l'espoir que les données de l'utilisateur ne sont pas déjà corrompues, mais il n'y a par définition pas de méthode standard de gérer un comportement indéfini.
la source