c++ - with - std:: exception e what




Attraper les exceptions de violation d'accès? (6)

Exemple

int *ptr;
*ptr = 1000;

puis-je intercepter l'exception de violation d'accès mémoire en utilisant le standard C ++ sans utiliser de microsoft spécifique.


Au moins pour moi, l'approche de signal(SIGSEGV ...) mentionnée dans une autre réponse n'a pas fonctionné sur Win32 avec Visual C ++ 2015 . Qu'est - ce qui a fonctionné pour moi était d'utiliser _set_se_translator() trouvé dans eh.h Cela fonctionne comme ceci:

Étape 1 ) Assurez-vous d'activer Oui avec SEH Exceptions (/ 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' exception. On l'appelle un traducteur car il prend simplement l'exception de bas niveau et la relance comme quelque chose de plus facile à attraper, comme std::exception :

// 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();
};

Ce type de situation dépend de la mise en œuvre et, par conséquent, il faudra un mécanisme spécifique au fournisseur pour piéger. Avec Microsoft cela impliquera SEH, et * nix impliquera un signal

En général, l'interception d'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 ne fera que rendre plus difficile de trouver des bogues dans votre programme.


Il existe un moyen très simple d'intercepter n'importe quel type d'exception (division par zéro, violation d'accès, etc.) dans Visual Studio à l' aide du bloc try -> catch (...). Un réglage mineur des paramètres du projet est suffisant. Activez simplement l'option / EHa dans les paramètres du projet. Voir Propriétés du projet -> C / C ++ -> Génération de code -> Modifier l'option Activer les exceptions C ++ à "Oui avec des exceptions SEH" . C'est tout!

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


Lit ça et pleure!

Je l'ai compris. Si vous ne lancez pas depuis le gestionnaire, le gestionnaire continuera simplement et l'exception aussi.

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

#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");

}

Pas le mécanisme de gestion des exceptions, Mais vous pouvez utiliser le mécanisme signal () qui est 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


Une violation comme celle-là signifie qu'il y a quelque chose qui ne va pas dans le code, et ce n'est pas fiable. Je peux voir qu'un programme peut vouloir essayer d'enregistrer les données de l'utilisateur d'une manière que l'on espère ne pas écrire 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 pas de méthode standard de traiter avec un comportement indéfini.







exception-handling