Exemplo
int *ptr;
*ptr = 1000;
posso capturar exceção de violação de acesso à memória usando C ++ padrão sem usar qualquer microsoft específico.
c++
exception-handling
Ahmed disse
fonte
fonte
Leia e chore!
Eu descobri. Se você não lançar do manipulador, o manipulador apenas continuará e também a exceção.
A mágica acontece quando você lança sua própria exceção e lida com isso.
#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"); }
fonte
sigaltstack
) instalado (a menos que a implementação de desenrolamento de exceção C ++ permita), e cada função de tempo de execução que manipula o próprio mecanismo de desenrolamento deve ser seguro para sinais.signal(SIGSEGV, SIG_DFL);
Há uma maneira muito fácil de capturar qualquer tipo de exceção (divisão por zero, violação de acesso, etc.) no Visual Studio usando o bloco try -> catch (...). Um pequeno ajuste nas configurações do projeto é o suficiente. Basta habilitar a opção / EHa nas configurações do projeto. Consulte Propriedades do projeto -> C / C ++ -> Geração de código -> Modifique a opção Ativar exceções C ++ para "Sim com exceções SEH" . É isso aí!
Veja os detalhes aqui: http://msdn.microsoft.com/en-us/library/1deeycx5(v=vs.80).aspx
fonte
Pelo menos para mim, a
signal(SIGSEGV ...)
abordagem mencionada em outra resposta não funcionou no Win32 com Visual C ++ 2015 . O que funcionou para mim foi usar_set_se_translator()
found ineh.h
. Funciona assim:Etapa 1 ) Certifique-se de habilitar Yes with SEH Exceptions (/ EHa) em Project Properties / C ++ / Code Generation / Enable C ++ Exceptions , conforme mencionado na resposta de Volodymyr Frytskyy .
Etapa 2 ) Chame
_set_se_translator()
, passando um ponteiro de função (ou lambda) para o novo tradutor de exceção . É chamado de tradutor porque basicamente pega a exceção de baixo nível e a re-lança como algo mais fácil de detectar, comostd::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()); });
Etapa 3 ) Capture a exceção como faria normalmente:
try{ MakeAnException(); } catch(std::exception ex){ HandleIt(); };
fonte
Esse tipo de situação depende da implementação e, conseqüentemente, exigirá um mecanismo específico do fornecedor para fazer o trap. Com a Microsoft, isso envolverá SEH, e * nix envolverá um sinal
Em geral, capturar uma exceção de violação de acesso é uma ideia muito ruim. Quase não há maneira de se recuperar de uma exceção AV e tentar fazer isso apenas tornará mais difícil encontrar bugs no seu programa.
fonte
Conforme declarado, não existe uma maneira que não seja da Microsoft / fornecedor de compilador de fazer isso na plataforma Windows. No entanto, é obviamente útil capturar esses tipos de exceções na maneira normal try {} catch (exception ex) {} para relatórios de erros e mais uma saída elegante de seu aplicativo (como diz JaredPar, o aplicativo agora provavelmente está com problemas) . Usamos _se_translator_function em um wrapper de classe simples que nos permite capturar as seguintes exceções em um manipulador try:
A classe original veio deste artigo muito útil:
http://www.codeproject.com/KB/cpp/exception.aspx
fonte
Não é o mecanismo de tratamento de exceção, mas você pode usar o mecanismo signal () que é fornecido pelo C.
> man signal 11 SIGSEGV create core image segmentation violation
Escrever para um ponteiro NULL provavelmente causará um sinal SIGSEGV
fonte
signal()
faz parte do padrão posix. Windows implementa o padrão posix (assim como Linux e unix)Uma violação como essa significa que há algo muito errado com o código e ele não é confiável. Eu posso ver que um programa pode querer tentar salvar os dados do usuário de uma forma que se espere não sobrescrever os dados anteriores, na esperança de que os dados do usuário já não estejam corrompidos, mas por definição não existe um método padrão de lidar com comportamento indefinido.
fonte