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.
To expand on all the answers here's what I found to work best for 100M+ installs:
std::set_terminate and std::set_unexpected perhaps should also be mentioned.
And the most important part to get it all right:
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();
}
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/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With