My code is compiled as a Windows DLL with Visual C++. I want to log rare cases when terminate() is being called, so I set my terminate() handler in the library initialization function and the latter is called by the user code before using my library. My handler writes to the log and calls abort() emulating the default terminate() behavior.
The problem is the user code might also be written in C++ and use the very same C++ runtime version and so share the terminate() handler with my library. That code might also want to alter the terminate() handler to have their logging. So they would call set_terminate(), then load and initialize my library and my library would also call set_terminate() and override their terminate() handler and that will be very hard for them to detect since the terminate() handler is the last thing they would test I suppose.
So I want the following. Inside the library initialization function I will retrieve the current terminate() handler, find whether it is a standard one, then if it happens to be a non-standard one, I will store its address and later (if needed) my terminate() handler will write into the log and then forward the call to that custom terminate() handler.
Is it possible to find if a terminate() handler currently installed is a default one or a custom one?
Do it via RAII like this:
class terminate_scope
{
public:
terminate_function _prev;
terminate_scope(terminate_function f = NULL){
_prev = set_terminate(f);
}
~terminate_scope(){
set_terminate(_prev);
}
};
To use:
void MyFunctionWantsOwnTerminateHandler(){
terminate_scope termhandler(&OwnTerminateHandler);
// terminate handler now set
// All my code will use that terminate handler
// On end of scope, previous terminate handler will be restored automatically
}
You can have the terminate handler chain the previous one if you are absolutely sure you need to.
MSDN vaguely says that
If no previous function has been set, the return value (of set_terminate) may be used to restore the default behavior; this value may be NULL;
and the same for _get_terminate. I find it not really helpful, because if the returned value is not NULL, still there is no guarantee that it is a valid terminate handler. One possible solution is to use GetModuleHandleEx with GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS to find out if the address returned by set_terminate is a valid address in any module.
Related
I'm looking for a way to change the exit status of a C/C++ program during an atexit callback sequence.
I'm develping some C++ code that registers a book keeping function with atexit. If the program terminates as a result of an exit() call, this book keeping function prints a message if the data was left in an incomplete state. If this is the case, I want to make sure that the exit status of the program is nonzero. This is probably going to be true anyway, but it's also possible to call exit(0).
One solution is to call exit(-1) within the book keeping function that I've registered with atexit. This seems to work, but I think it's also undefined behavior. Does anyone know if this is correct? It's also unclear if this would terminate the atexit callback chain, which would be bad if there's another critical function registered with atexit.
On POSIX systems, it is allowed to call _exit from within an atexit handler, however doing so means that any other atexit handler is not called.
Since atexit handlers are called in the reverse order of registration, have the first registered handler read a global variable and, if it's not set to some initial sentinel value, call _exit with that value. Then any other handlers you register can modify that global if they want to override the exit value passed to exit.
For example:
#define EXIT_DEFAULT 0xffff
int exit_override = EXIT_DEFAULT;
void override_exit(void)
{
if (exit_override != EXIT_DEFAULT) _exit(exit_override);
}
void handler1(void)
{
if (some_error_condition) exit_override = 1;
}
int main()
{
atexit(override_exit);
atexit(handler1);
// do something that might call exit
return 0;
}
We're on Windows and we want to get a crash dump (possibly using MiniDumpWriteDump) for all scenarios where our application exit's unexpectedly.
So far we have identified, and set up, the following:
SetUnhandledExceptionFilter for unhandled exception (Win32 as well as "normal" C++ ones.)
_set_invalid_parameter_handler for the CRT invalid argument handling
_set_abort_behaviorplus a SIGABRT handler to account for calls to abort()
Is there anything we missed? (Modulo some code non-legitimately calling ExitProcess, TerminateProcess or one of the exit variants.)
I'll note that this question here is orthogonal to how a crash dump is then obtained. E.g., if you want a crash dump in case of abort, you always must use _set_abort_behaviour because otherwise abort just exits.
I'll also note that on Windows7+, not setting SetUHEF and just setting up the "correct" WER dump settings in the registry is often a viable way.
I use exactly the ones you've listed, plus _set_purecall_handler, plus this handy snippet of code:
void EnableCrashingOnCrashes()
{
typedef BOOL (WINAPI *tGetPolicy)(LPDWORD lpFlags);
typedef BOOL (WINAPI *tSetPolicy)(DWORD dwFlags);
static const DWORD EXCEPTION_SWALLOWING = 0x1;
const HMODULE kernel32 = LoadLibraryA("kernel32.dll");
const tGetPolicy pGetPolicy = (tGetPolicy)GetProcAddress(kernel32, "GetProcessUserModeExceptionPolicy");
const tSetPolicy pSetPolicy = (tSetPolicy)GetProcAddress(kernel32, "SetProcessUserModeExceptionPolicy");
if(pGetPolicy && pSetPolicy)
{
DWORD dwFlags;
if(pGetPolicy(&dwFlags))
{
// Turn off the filter
pSetPolicy(dwFlags & ~EXCEPTION_SWALLOWING);
}
}
}
Source:
http://randomascii.wordpress.com/2012/07/05/when-even-crashing-doesnt-work/
These other articles on his site also helped me understand this:
http://randomascii.wordpress.com/2011/12/07/increased-reliability-through-more-crashes/
http://randomascii.wordpress.com/2012/07/22/more-adventures-in-failing-to-crash-properly/
SetUnhandledExceptionFilter is emphatically not enough to capture all unexpected exits. If an application accidentally calls a pure virtual function then a dialog will pop up. The application will hang, but not crash. Since there is no exception neither SetUnhandledExceptionFilter nor WER can help. There are a few variations on this theme.
Worse yet is the weirdness if you crash in a kernel callback such as a WindowProc. If this happens in a 32-bit application on 64-bit Windows then the exception is caught by the OS and execution continues. Yes, the crash is silently handed. I find that terrifying.
http://randomascii.wordpress.com/2012/07/05/when-even-crashing-doesnt-work/ should detail all of the tricks needed to handle these unusual cases.
To expand on all the answers here's what I found to work best for 100M+ installs:
SetErrorMode to prevent any WER dialogs showing up.
EnableCrashingOnCrashes
PreventSetUnhandledExceptionFilter
SetUnhandledExceptionFilter for system exceptions.
_set_invalid_parameter_handler for the CRT invalid argument handling
_set_abort_behavior plus a SIGABRT handler to account for calls to abort()
std::set_terminate and std::set_unexpected perhaps should also be mentioned.
And the most important part to get it all right:
all these handlers should call a function that executes under a mutex/critical section to ensure that if there are any other crashes happening in other threads at the same time they would all stop and wait instead of causing havoc.
signal handler for SIGABRT must set itself back as a SIGABRT handler! Without this if you get crashes happening at the same time from other threads you process will exit immediately without giving you any time to handle the crash.
actual handling of the error should ideally happen in another process, or at least in another thread that was started at the beginning of the process, otherwise you won't be able to handle low memory conditions or stackoverflow errors.
See setExceptionHandlers below for reference. Also, most likely you don't want to hook up all the handlers in debug builds or when IsDebuggerPresent.
#include <signal.h>
#include <windows.h>
#include <boost/thread/mutex.hpp>
void EnableCrashingOnCrashes();
void PreventSetUnhandledExceptionFilter();
static void exceptionHandler(EXCEPTION_POINTERS* excpInfo)
{
// your code to handle the exception. Ideally it should
// marshal the exception for processing to some other
// thread and waif for the thread to complete the job
}
static boost::mutex unhandledExceptionMx;
static LONG WINAPI unhandledException(EXCEPTION_POINTERS* excpInfo = NULL)
{
boost::mutex::scoped_lock lock(unhandledExceptionMx);
if (!excpInfo == NULL)
{
__try // Generate exception to get proper context in dump
{
RaiseException(EXCEPTION_BREAKPOINT, 0, 0, NULL);
}
__except (exceptionHandler(GetExceptionInformation()), EXCEPTION_EXECUTE_HANDLER)
{
}
}
else
{
exceptionHandler(excpInfo);
}
return 0;
}
static void invalidParameter(const wchar_t* expr, const wchar_t* func,
const wchar_t* file, unsigned int line, uintptr_t reserved)
{
unhandledException();
}
static void pureVirtualCall()
{
unhandledException();
}
static void sigAbortHandler(int sig)
{
// this is required, otherwise if there is another thread
// simultaneously tries to abort process will be terminated
signal(SIGABRT, sigAbortHandler);
unhandledException();
}
static void setExceptionHandlers()
{
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
SetUnhandledExceptionFilter(unhandledException);
_set_invalid_parameter_handler(invalidParameter);
_set_purecall_handler(pureVirtualCall);
signal(SIGABRT, sigAbortHandler);
_set_abort_behavior(0, 0);
EnableCrashingOnCrashes();
PreventSetUnhandledExceptionFilter();
}
Tall order, just in brief:
You need not to use any other _set* functions, SetUnhandledExceptionFilter is enough for all.
C runtime functions like abort will disable the global exception handler, which you setup using SetUnhandledExceptionFilter. CRT will simply call this same function will NULL parameter, and your exception-handler is disabled (not called), if CRT is causing crash! What you can do? [X]
Disable all other running threads when the excption-handler gets called. Just lookup all threads using CreateToolhelp32Snapshot, and other functions. Look for this process, and suspend all other running threads (except current, ofcourse).
Use SEH or no-SEH, global-exception handler gets called unless CRT interfers. Not to worry (in MOST cases).
Do not any CLR in-between, it will not allow the exception handler to call, if any CLR/managed call (yes from C/C++) comes in between.
You cannot handle one exception - Stack Overflow! Think! Running under a debugger is only solution, see below.
There is more to it, which I haven't tried (not found usefulness) - Vectored Exception Handling.
One other approach is to run the application into a debugger, which you can craft yourself! In the debugger, you can catch ALL exceptions, just like VS debugger catches. See my article. But, you know, this is not proper approach.
EDIT: Just read the last content about process-termination. You shouldn't control that. In any case, you can just hook the required APIs, which would act as what you code for (like displaying message box).
[X] You need to use API hooking. I dont have link and details handy. You'd hook other related APIs, but primarily the SetUnhandledExceptionFilter (after you'd called it for you). You dummy (hooked) function will look like:
xxx SetUnhandledExceptionFilter_DUMMY(xxx)
{
// Dont do any thing
return NULL;
}
I dont have link and details of API hooking handy.
And why not attempt to make your application more safe?
Correct all warnings (yes, even level 4).
Use static analysis. VS itself has (in higher versions, though. Except 2012 - all variants have). Other SA tools are available.
Do careful code-reviewing. It pays!
Run and Debug your RELEASE build from the debugger. Use all features.
Look and correct all possible memory leaks.
Use defensive approach to programming. Rather than checking if null, defend it using ASSERT, or your own assert. Pack it with assertion, log, return from function.
I will add a workaround that one can use in certain scenarios when running on Windows 7:
Windows Error Reporting (WER) offers the option to write full memory dumps on app crash.
So, if you are fine with that, you "just" have to make sure that the crash scenarios you're actually interested in will trigger WER. ... Which, really, leads us back to this very question, but still ...
You can catch any exception with WER. As you have seen the CRT sometimes forces to call WER.
If you want to always catch excpetion in-process, you need to prevent the calling of SetUnhandledExceptionFilter(NULL) from the CRT. For more info see my blog entry: Improved “PreventSetUnhandledExceptionFilter”
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?
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.
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 too - see his comment below.
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.
What's the difference between those three, and how shall I end program in case of exception which I can't handle properly?
abort indicates "abnormal" end to the program, and raises the the POSIX signal SIGABRT, which means that any handler that you have registered for that signal will be invoked, although the program will still terminate afterwords in either case. Usually you would use abort in a C program to exit from an unexpected error case where the error is likely to be a bug in the program, rather than something like bad input or a network failure. For example, you might abort if a data structure was found to have a NULL pointer in it when that should logically never happen.
exit indicates a "normal" end to the program, although this may still indicate a failure (but not a bug). In other words, you might exit with an error code if the user gave input that could not be parsed, or a file could not be read. An exit code of 0 indicates success. exit also optionally calls handlers before it ends the program. These are registered with the atexit and on_exit functions.
std::terminate is what is automatically called in a C++ program when there is an unhandled exception. This is essentially the C++ equivalent to abort, assuming that you are reporting all your exceptional errors by means of throwing exceptions. This calls a handler that is set by the std::set_terminate function, which by default simply calls abort.
In C++, you usually want to avoid calling abort or exit on error, since you're better off throwing an exception and letting code further up the call stack decide whether or not ending the program is appropriate. Whether or not you use exit for success is a matter of circumstance - whether or not it makes sense to end the program somewhere other than the return statement in main.
std::terminate should be considered a last-ditch error reporting tool, even in C++. The problem with std::terminate is that the terminate handler does not have access to the exception that went unhandled, so there's no way to tell what it was. You're usually much better off wrapping the entirety of main in a try { } catch (std::exception& ex) { } block. At least then you can report more information about exceptions that derived from std::exception (although of course exceptions that do not derive from std::exception would still end up unhandled).
Wrapping the body of main in try { } catch(...) { } isn't much better than setting a terminate handler, because again you have no access to the exception in question. There is at least one benefit, though: whether stack unwinding is done when an exception goes completely uncaught is implementation defined, so if you need guaranteed stack unwinding, this would be a way to get that.
std::abort and std::exit (and more: std::_Exit, std::quick_exit) are just lower level functions. You use them to tell the program what you want it to do exactly: what destructors (and if) to call, what other clean-up functions to call, what value to return, etc.
std::terminate is a higher level abstraction: it is called (by either run-time or you) to indicate that an error in the program occurred and that for some reason it is not possible to handle by throwing an exception. The necessity for that typically occurs when error occurs in the exception mechanism itself, but you can use it any time when you do not want your program to continue beyond the given error. I compiled the full list of situations when std::terminate is called in my post. It is not specified what std::terminate does, because you are in control of it. You can configure the behavior by registering any functions. The limitations you have are that the function cannot return back to the error site and it cannot exit via an exception, but technically you can even start your message pump inside. For the list of useful things that you can do inside, see my other post.
In particular, note that std::terminate is considered an exception handler in contexts where std::terminate is called due to a thrown exception that could not be handled, and you can check what the exception was and inspect it by using C++11 using std::rethrow_exception and std::current_exception. It is all in my post.
quick_exit() !
If your program is multi-threaded, then calling exit() will most likely result in a crash because global/static std::thread objects will be attempted to destruct without exiting their threads.
If you want to return an error code and exit the program (more or less) normally, call quick_exit() in multi-threaded programs.
For abnormal termination (without a possibility for you to specify the error code), abort() or std::terminate() can be called.
Note: quick_exit() has not been supported by MSVC++ until version 2015 .
terminate() is automatically called
when an exception occurs that cannot
be handled. By default, terminate()
calls abort(). You can set a custom
handle with set_terminate() function.
abort() sends the SIGABRT signal.
exit() is not necessarily a bad
thing. It successfully exits the
application, and calls atexit()
functions in LIFO order. I don't
normally see this in C++
applications, however, I do see it in
many unix based applications where it
sends an exit code at the end.
Usually a exit(0) indicates a
successful run of the application.
terminate leaves you the possibility to register what will happen when it is called. Should be one of the other two.
exit is a normal exit allowing to specify an exit status. Handlers registered by at_exit() are run
abort is an abnormal exit. The only thing which is ran is the signal handler for SIGABRT.
My advice would be not to use any of them. Instead, catch the exceptions you can't handle in main() and simply return from there. This means that you are guaranteed that stack unwinding happens correctly and all destructors are called. In other words:
int main() {
try {
// your stuff
}
catch( ... ) {
return 1; // or whatever
}
}
The C++ standard provides the std::set_terminate function which lets you specify what function std::terminate should actually call. std::terminate should only get called in dire circumstances, and sure enough the situations the standard describes for when it's called are dire (e.g. an uncaught exception). When std::terminate does get called the situation seems analagous to being out of memory -- there's not really much you can sensibly do.
I've read that it can be used to make sure resources are freed -- but for the majority of resources this should be handled automatically by the OS when the process exits (e.g. file handles). Theoretically I can see a case for if say, you needed to send a server a specific message when exiting due to a crash. But the majority of the time the OS handling should be sufficient.
When is using a terminate handler the Right Thing(TM)?
Update: People interested in what can be done with custom terminate handlers might find this non-portable trick useful.
This is just optimistic:
but for the majority of resources this should be handled automatically by the OS when the process exits
About the only resources that the OS handles automatically are "File Handles" and "Memory" (And this may vary across OS's).
Practically all other resources (and if somebody has a list of resources that are automatically handled by OS's I
would love that) need to be manually released by the OS.
Your best bet is to avoid exit using terminate() and try a controlled shut down by forcing the stack to unwind correctly.
This will make sure that all destructors are called correctly and your resources are released (via destructors).
About the only thing I would do is log the problem. So that when it does happened I could go back and fix the code so that it does not happen again. I like my code to unwind the stack nicely for resource deallocation, but this is an opinion some people like abrupt halts when things go badly.
My list of when terminate is called:
In general it is called when the exception handling mechanism cannot find a handler for a thrown exception. Some specific examples are:
An exception escapes main()
Note: It is implementation defined whether the stack is unwound here.
Thus I always catch in main and then rethrow (if I do not explicitly handle).
That way I guarantee unwinding of the stack (across all platforms) and still get the benefits of the OS exception handling mechanism.
Two exceptions propagating simultaneously.
An exception escapes a desatructor while another exception is propagating.
The expression being thrown generates an exception
An exception before or after main.
If an exception escapes the constructor/destructor of a global object.
If an exception escapes the destructor of a function static variable.
(ie be careful with constructors/destructors of nonlocal static object)
An exception escapes a function registered with atexit().
A rethrow when no exception is currently propagating.
An unlisted exception escapes a method/function that has exception specifier list.
via unexpected.
Similar to a statement made in Martin York's answer, about the only thing I do in a custom terminate handler is log the problem so I can identify and correct the offending code. This is the only instance I find that using a custom terminate handler is the Right Thing.
Since it is implementation-defined whether or not the stack is unwound before std::terminate() is called, I sometimes add code to generate a backtrace in order to locate an uncaught exception1.
1) This seems to work for me when using GCC on Linux platforms.
I think the right question would be how to avoid the calls to terminate handler, rather than when to use it.