c++ - tipo - try catch en c
¿Captura todas las excepciones de C++ no controladas? (8)
¿Hay alguna forma de detectar excepciones que de otro modo no se han controlado (incluidas las lanzadas fuera del bloque catch)?
No estoy realmente preocupado por todas las cosas normales de limpieza hechas con excepciones, solo que puedo atraparlo, escribirlo para registrar / notificar al usuario y salir del programa, ya que las excepciones en estos casos son en general errores fatales e irrecuperables.
algo como:
global_catch()
{
MessageBox(NULL,L"Fatal Error", L"A fatal error has occured. Sorry for any inconvience", MB_ICONERROR);
exit(-1);
}
global_catch(Exception *except)
{
MessageBox(NULL,L"Fatal Error", except->ToString(), MB_ICONERROR);
exit(-1);
}
Esto se puede usar para detectar excepciones inesperadas.
catch (...)
{
cout << "OMG! an unexpected exception has been caught" << endl;
}
Sin un bloque try catch, no creo que pueda detectar excepciones, por lo que es necesario estructurar su programa, por lo que el código de excepción está bajo el control de un try / catch.
Puede usar SetUnhandledExceptionFilter en Windows, que capturará todas las excepciones SEH no controladas.
En general, esto será suficiente para todos sus problemas como IIRC todas las excepciones de C ++ se implementan como SEH.
Sin ningún bloque catch, no captarás ninguna excepción. Puede tener un bloque catch (...) en su main () (y su equivalente en cada thread adicional). En este bloque catch, puede recuperar los detalles de la excepción y puede hacer algo al respecto, como iniciar sesión y salir.
Sin embargo, también hay una desventaja sobre un bloque de captura general (...): el sistema encuentra que la excepción ha sido manejada por usted, por lo que no le da más ayuda. En Unix / Linux, esta ayuda constituiría la creación de un archivo CORE, que podría cargar en el depurador y ver la ubicación original de la excepción no aceptada. Si lo está manejando con catch (...) esta información ya estaría perdida.
En Windows, no hay archivos CORE, por lo que sugeriría tener el bloque catch (...). Desde ese bloque, normalmente se llama a una función para resucitar la excepción real:
std::string ResurrectException()
try {
throw;
} catch (const std::exception& e) {
return e.what();
} catch (your_custom_exception_type& e) {
return e.ToString();
} catch(...) {
return "Ünknown exception!";
}
}
int main() {
try {
// your code here
} catch(...) {
std::string message = ResurrectException();
std::cerr << "Fatal exception: " << message << "/n";
}
}
Use catch (...) en todas sus barreras de excepción (no solo en el hilo principal). Sugiero que siempre vuelva a lanzar (...) y redirija la salida / error estándar al archivo de registro, ya que no puede hacer RTTI significativo activado (...). OTOH, compilador como GCC generará una descripción bastante detallada sobre la excepción no controlada: el tipo, el valor de qué (), etc.
Siempre que C ++ 11 esté disponible, se puede utilizar este enfoque (ver ejemplo de: http://en.cppreference.com/w/cpp/error/rethrow_exception ):
#include <iostream>
#include <exception>
void onterminate() {
try {
auto unknown = std::current_exception();
if (unknown) {
std::rethrow_exception(unknown);
} else {
std::cerr << "normal termination" << std::endl;
}
} catch (const std::exception& e) { // for proper `std::` exceptions
std::cerr << "unexpected exception: " << e.what() << std::endl;
} catch (...) { // last resort for things like `throw 1;`
std::cerr << "unknown exception" << std::endl;
}
}
int main () {
std::set_terminate(onterminate); // set custom terminate handler
// code which may throw...
return 0;
}
Este enfoque también le permite personalizar la salida de la consola para excepciones no controladas: tener algo como esto
unexpected exception: wrong input parameters
Aborted
en lugar de esto:
terminate called after throwing an instance of ''std::logic_error''
what(): wrong input parameters
Aborted
Actualización : Esto cubre solo c ++ 98.
Desde C ++ más efectivo por Meyers (pg 76), podría definir una función a la que se llama cuando una función genera una excepción que no está definida por su especificación de excepción.
void convertUnexpected()
{
// You could redefine the exception here into a known exception
// throw UnexpectedException();
// ... or I suppose you could log an error and exit.
}
En su aplicación, registre la función:
std::set_unexpected( convertUnexpected );
Se llamará a su función convertUnexpected () si una función genera una excepción que no está definida por su especificación de excepción ... lo que significa que esto solo funciona si está utilizando especificaciones de excepción. ; (
Echa un vistazo a std::set_terminate()
Esto es lo que siempre hago en main ()
int main()
{
try
{
// Do Work
}
catch(std::exception const& e)
{
Log(e.what());
// If you are feeling mad (not in main) you could rethrow!
}
catch(...)
{
Log("UNKNOWN EXCEPTION");
// If you are feeling mad (not in main) you could rethrow!
}
}