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

后端 未结 3 1645
时光说笑
时光说笑 2020-11-27 03:33

Our unit tests fire off child processes, and sometimes these child processes crash. When this happens, a Windows Error Reporting dialog pops up, and the process stays alive

3条回答
  •  不知归路
    2020-11-27 03:40

    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

提交回复
热议问题