views:

102

answers:

4
+1  Q: 

c++ abort override

Some C++ libraries call abort() function in the case of error (for example, SDL). No helpful debug information is provided in this case. It is not possible to catch abort call and to write some diagnostics log output. I would like to override this behaviour globally without rewriting/rebuilding these libraries. I would like to throw exception and handle it. Is it possible?

A: 

No. abort() is a standard library function, and has no replacement mechanism. It's also the quickest way to end your program, skipping both destructors and atexit functions.

Your best bet is to try and stop the errors from happening by checking values before you make calls to the library.

GMan
Umm, Tony's right. And the abort handler is not allowed to return, but both longjmp and exceptions give alternate ways of leaving the handler and continuing execution.
Ben Voigt
@Ben Oh, I forgot about signals. Granted they're implementation-defined, but meep. Wish I could delete...
GMan
+1  A: 

You could try writing your own and get the linker to call yours in place of std::abort. I'm not sure if it is possible however.

verisimilidude
+2  A: 

According to the man page on Linux, abort() generates a SIGABRT to the process that can be caught by a signal handler. EDIT: Ben's confirmed this is possible on Windows to - see his comment below.

Tony
Visual C++'s abort function does too. <quote>void abort() - abort the current program by raising SIGABRT Purpose: print out an abort message and raise the SIGABRT signal. If the user hasn't defined an abort handler routine, terminate the program with exit status of 3 without cleaning up.</quote>
Ben Voigt
+1  A: 

Note that abort raises the SIGABRT signal, as if it called raise(SIGABRT). You can install a signal handler that gets called in this situation, like so:

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

If you can't prevent the abort calls (say, they're due to bugs that creep in despite your best intentions), this might allow you to collect some more debugging information. This is portable ANSI C, so it works on Unix and Windows, and other platforms too, though what you do in the abort handler will often not be portable. Note that this handler is also called when an assert fails, or even by other runtime functions - say, if malloc detects heap corruption. So your program might be in a crazy state during that handler. You shouldn't allocate memory - use static buffers if possible. Just do the bare minimum to collect the information you need, get an error message to the user, and quit.

Certain platforms may allow their abort functions to be customized further. For example, on Windows, Visual C++ has a function _set_abort_behavior that lets you choose whether or not a message is displayed to the user, and whether crash dumps are collected.

Doug
What if my_function_to_handle_aborts throws? )
topright
@Pavel: it's implementation-defined, i.e. not portable. Basically, you are guaranteed to be able to use the features of C, but you might not be able to use C++ features like declaring variables, calling `new`, `delete`, or throwing exceptions. In a lot of implementations, it might work, though. Also, the function is supposed to have C linkage - I've edited the answer, but it's unlikely to make a difference on Windows or Unix.
Doug
@Doug, Thank you for the detailed answer.
topright