Attraper des exceptions de violation d’access?

Exemple

int *ptr; *ptr = 1000; 

puis-je intercepter une exception de violation d’access à la mémoire à l’aide de C ++ standard sans utiliser de Microsoft spécifique.

Nan. C ++ ne lance pas d’exception lorsque vous faites quelque chose de mal, ce qui entraînerait un impact sur les performances. Des éléments tels que les violations d’access ou les erreurs de division par zéro s’apparentent davantage à des exceptions “machine”, plutôt qu’à des problèmes de niveau linguistique que vous pouvez rencontrer.

Lit ça et pleure!

Je l’ai compris. Si vous ne lancez pas à partir du gestionnaire, le gestionnaire continuera simplement, de même que l’exception.

La magie se produit lorsque vous lancez votre propre exception et gérez cela.

 #include "stdafx.h" #include  #include  #include  #include  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"); } 

Il existe un moyen très simple d’attraper toute sorte d’exception (division par zéro, violation d’access, etc.) dans Visual Studio en utilisant le bloc try -> catch (…). Un ajustement mineur des parameters du projet est suffisant. Activez simplement l’option / EHa dans les parameters du projet. Voir Propriétés du projet -> C / C ++ -> Génération de code -> Modifier les exceptions Activer C ++ à “Oui avec exceptions SEH” . C’est tout!

Voir les détails ici: http://msdn.microsoft.com/en-us/library/1deeycx5(v=vs.80).aspx

Ce type de situation dépend de l’implémentation et nécessite par conséquent un mécanisme spécifique au fournisseur pour pouvoir intercepter. Avec Microsoft, cela impliquera SEH, et * nix impliquera un signal

En général, attraper une exception de violation d’access est une très mauvaise idée. Il n’y a presque aucun moyen de récupérer d’une exception AV et tenter de le faire ne fera que rendre plus difficile la recherche de bogues dans votre programme.

Comme indiqué, il n’y a pas de moyen de fournisseur non Microsoft / compilateur pour faire cela sur la plate-forme Windows. Cependant, il est évidemment utile d’attraper ces types d’exceptions de la manière habituelle try {} catch (exception ex) {} pour les rapports d’erreurs et plus une sortie élégante de votre application (comme le dit JaredPar, l’application est probablement en difficulté) . Nous utilisons _se_translator_function dans un wrapper de classe simple qui nous permet de détecter les exceptions suivantes dans un gestionnaire try:

 DECLARE_EXCEPTION_CLASS(datatype_misalignment) DECLARE_EXCEPTION_CLASS(breakpoint) DECLARE_EXCEPTION_CLASS(single_step) DECLARE_EXCEPTION_CLASS(array_bounds_exceeded) DECLARE_EXCEPTION_CLASS(flt_denormal_operand) DECLARE_EXCEPTION_CLASS(flt_divide_by_zero) DECLARE_EXCEPTION_CLASS(flt_inexact_result) DECLARE_EXCEPTION_CLASS(flt_invalid_operation) DECLARE_EXCEPTION_CLASS(flt_overflow) DECLARE_EXCEPTION_CLASS(flt_stack_check) DECLARE_EXCEPTION_CLASS(flt_underflow) DECLARE_EXCEPTION_CLASS(int_divide_by_zero) DECLARE_EXCEPTION_CLASS(int_overflow) DECLARE_EXCEPTION_CLASS(priv_instruction) DECLARE_EXCEPTION_CLASS(in_page_error) DECLARE_EXCEPTION_CLASS(illegal_instruction) DECLARE_EXCEPTION_CLASS(noncontinuable_exception) DECLARE_EXCEPTION_CLASS(stack_overflow) DECLARE_EXCEPTION_CLASS(invalid_disposition) DECLARE_EXCEPTION_CLASS(guard_page) DECLARE_EXCEPTION_CLASS(invalid_handle) DECLARE_EXCEPTION_CLASS(microsoft_cpp) 

La classe originale est venue de cet article très utile:

http://www.codeproject.com/KB/cpp/exception.aspx

Au moins pour moi, l’approche du signal(SIGSEGV ...) mentionnée dans une autre réponse ne fonctionnait pas sur Win32 avec Visual C ++ 2015 . Ce qui a fonctionné pour moi a été d’utiliser _set_se_translator() trouvé dans eh.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 indiqué dans la réponse de Volodymyr Frytskyy .

Étape 2 ) Appelez _set_se_translator() en transmettant un pointeur de fonction (ou lambda) pour le nouveau traducteur d’ exception. Il s’appelle un traducteur car il prend simplement l’exception de bas niveau et le relance comme quelque chose de plus facile à attraper, tel que std::exception :

 #include  #include  // Be sure to enable "Yes with SEH Exceptions (/EHa)" in C++ / Code Generation; _set_se_translator([](unsigned int u, EXCEPTION_POINTERS *pExp) { std::ssortingng 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(); }; 

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 dans un pointeur NULL va probablement provoquer un signal SIGSEGV

Une telle violation signifie que quelque chose ne va pas avec le code, et que ce n’est pas fiable. Je peux voir qu’un programme voudra peut-être essayer de sauvegarder les données de l’utilisateur de manière à ce qu’il espère ne pas écrire sur les données précédentes, dans l’espoir que les données de l’utilisateur ne soient pas déjà corrompues. de traiter avec un comportement indéfini.