I have a c++ program on windows that uses SetUnhandledExceptionFilter() at the very start of the program.
The intent is that the unhandledExceptionHandler
will store a minidump to disk and then the program will terminate.
In this top-level use-case, I am confused by the possible return values of the exception handler.
EXCEPTION_CONTINUE_SEARCH
? There are no other exception handlers to bubble up to (or are there?).
EXCEPTION_EXECUTE_HANDLER
?
It's used in the microsoft example but it is unclear what that handler does, since there is no __except
block when using SetUnhandledExceptionFilter
...
What are in this case the differences between
return EXCEPTION_CONTINUE_SEARCH
return EXCEPTION_EXECUTE_HANDLER
std::terminate()
in the unhandledExceptionHandler
Example of the program structure:
LONG WINAPI unhandledExceptionHandler(struct _EXCEPTION_POINTERS* apExceptionInfo)
{
/* Save a Minidump */
// ...
/* Terminate */
return EXCEPTION_CONTINUE_SEARCH;
}
int main(int argc, char** argv)
{
#ifdef WIN32
// Enables an application to supersede the top-level exception handler of each thread of a process.
// After calling this function, if an exception occurs in a process that is not being debugged,
// and the exception makes it to the unhandled exception filter,
// that filter will call the exception filter function specified by the lpTopLevelExceptionFilter parameter.
// Source:
// https://learn.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-setunhandledexceptionfilter
SetUnhandledExceptionFilter(unhandledExceptionHandler);
// related TODO: Do we compile with /EHa ? https://stackoverflow.com/a/4574319/2550406
// "When you want to make your objects safe for these kind of exceptions as well then you'll need to use /EHa, that tells the compiler to always register the exception filter.
// Beware of a nasty side-effect of /EHa, it makes catch(...) swallow all exceptions. Including the ones you should never catch, like AV and SO."
#endif
return runTheProgram();
}
Short answer:
To only store a minidump and do not change normal behavior, just store the minidump and return EXCEPTION_CONTINUE_SEARCH
. But pay attention that in some cases your process won't be terminated after executing the filter.
Long answer:
The purpose of calling SetUnhandledExceptionFilter
is to set a filter, not handler.
The filter should tell the runtime if in case of specific exception the program should:
EXCEPTION_CONTINUE_SEARCH
.EXCEPTION_EXECUTE_HANDLER
.EXCEPTION_CONTINUE_EXECUTION
. You can use this option if and only if you can recover the process from error state.Do not call std::terminate() in the filter function. It would be like:
Operating system:
Hey process, we encountered an error, what we should do? Would you like me to sort out the situation for you?Process:
Oh no, I'm in a panic!
[process terminated]Operating system:
Meh...