2010-10-12 14 views
5

Algunas bibliotecas C++ llaman a la función abort() en el caso de error (por ejemplo, SDL). No se proporciona información de depuración útil en este caso. No es posible capturar abortar llamada y escribir alguna salida de registro de diagnóstico. Me gustaría anular este comportamiento globalmente sin reescribir/reconstruir estas bibliotecas. Me gustaría lanzar una excepción y manejarlo. ¿Es posible?C++ abortar anular

Respuesta

17

Tenga en cuenta que abort levanta la señal SIGABRT, como si llamara raise(SIGABRT). Puede instalar un controlador de señal que es llamada en esta situación, así:

#include <signal.h> 

extern "C" void my_function_to_handle_aborts(int signal_number) 
{ 
    /*Your code goes here. You can output debugging info. 
     If you return from this function, and it was called 
     because abort() was called, your program will exit or crash anyway 
     (with a dialog box on Windows). 
    */ 
} 

/*Do this early in your program's initialization */ 
signal(SIGABRT, &my_function_to_handle_aborts); 

Si no se puede evitar que los abort llamadas (por ejemplo, son debido a los errores que se arrastran en el pesar de sus mejores intenciones), esto podría permitirle recopilar más información de depuración. Este es ANSI C portátil, por lo que funciona en Unix y Windows, y en otras plataformas también, aunque lo que haga en el controlador de aborto a menudo no será portátil. Tenga en cuenta que este controlador también se invoca cuando falla un assert, o incluso por otras funciones de tiempo de ejecución, por ejemplo, si malloc detecta daños en el montón. Entonces su programa podría estar en un estado loco durante ese controlador. No debe asignar memoria; use búferes estáticos si es posible. Simplemente haga lo mínimo posible para recopilar la información que necesita, obtenga un mensaje de error para el usuario y cierre.

Ciertas plataformas pueden permitir que sus funciones abort se personalicen aún más. Por ejemplo, en Windows, Visual C++ tiene una función _set_abort_behavior que le permite elegir si se muestra o no un mensaje al usuario y si se recopilan los volcados de emergencia.

+0

¿Qué pasa si mi_function_to_handle_aborts throws?) –

+0

@Pavel: su implementación está definida, es decir, no es portátil. Básicamente, tiene la garantía de poder usar las funciones de C, pero es posible que no pueda usar funciones de C++ como declarar variables, llamar a 'nuevo',' eliminar' o lanzar excepciones. Sin embargo, en muchas implementaciones, podría funcionar. Además, se supone que la función tiene un enlace C: he editado la respuesta, pero es poco probable que haga una diferencia en Windows o Unix. – Doug

+0

Gracias por la respuesta detallada. –

0

Puede intentar escribir el suyo y obtener el vinculador para llamar al suyo en lugar de std :: abort. No estoy seguro de si es posible, sin embargo.

3

De acuerdo con la página man de Linux, abort() genera un SIGABRT para el proceso que puede ser capturado por un manejador de señal. EDITAR: Ben ha confirmado que esto también es posible en Windows, mira su comentario a continuación.

+1

La función de cancelación de Visual C++ también lo hace. void abort() - aborta el programa actual levantando SIGABRT Propósito: imprime un mensaje de cancelación y sube la señal SIGABRT. Si el usuario no ha definido una rutina de administración de interrupción, finalice el programa con el estado de salida 3 sin limpiar.