How to terminate a program when it crashes? (which should just fail a unit test instead of getting stuck forever)

A summary from the answers by jdehaan and Eric Brown, as well as this question (see also this question):

N.B. These solutions may affect other error reporting as well, e.g. failure to load a DLL or open a file.

Option 1: Disable globally

Works globally on the entire user account or machine, which can be both a benefit and a drawback.

Set [HKLM|HKCU]\Software\Microsoft\Windows\Windows Error Reporting\DontShowUI to 1.
More info: WER settings.

Option 2: Disable for the application

Requires modification to the crashing program, described in documentation as best practice, unsuitable for a library function.

Call SetErrorMode: SetErrorMode(SetErrorMode(0) | SEM_NOGPFAULTERRORBOX); (or with SEM_FAILCRITICALERRORS). More info: Disabling the program crash dialog (explains the odd arrangement of calls).

Option 2a: Disable for a function:

Requires modification to the crashing program, requires Windows 7/2008 R2 (desktop apps only) or higher, described in documenation as preferred to SetErrorMode, suitable for a thread-safe library function.

Call and reset SetThreadErrorMode:

DWORD OldThreadErrorMode = 0;
SetThreadErrorMode(SEM_FAILCRITICALERRORS,& OldThreadErrorMode);
    …
SetThreadErrorMode (z_OldThreadErrorMode, NULL);

More info: not much available?

Option 3: Specify a handler

Requires modification to the crashing program.

Use SetUnhandledExceptionFilter to set your own structured exception handler that simply exits, probably with reporting and possibly an attempt at clean-up.

Option 4: Catch as an exception

Requires modification to the crashing program. For .NET applications only.

Wrap all code into a global try/catch block. Specify the HandleProcessCorruptedStateExceptionsAttribute and possibly also the SecurityCriticalAttribute on the method catching the exceptions. More info: Handling corrupted state exceptions

Note: this might not catch crashes caused by the Managed Debugging Assistants; if so, these also need to be disabled in the application.

Option 5: Stop the reporting process

Works globally on the entire user account, but only for a controlled duration.

Kill the Windows Error Reporting process whenever it shows up:

var werKiller = new Thread(() =>
{
    while (true)
    {
        foreach (var proc in Process.GetProcessesByName("WerFault"))
            proc.Kill();
        Thread.Sleep(3000);
    }
});
werKiller.IsBackground = true;
werKiller.Start();

This is still not completely bullet-proof though, because a console application may crash via a different error message, apparently displayed by an internal function called NtRaiseHardError:

alt text

Leave a Comment