I wrote this gist to explore multiple ways to disable Windows Error Reporting dialogs ("app has stopped working" messages) when starting a buggy application. Please note that there are many ways to disable WER dialogs globally. This gist, on the other hand, aims to disable WER for a specific application when starting it. This is useful when running such a buggy application in a script for example.
After cloning the gist, one can use CMake to build the application in visual studio:
mkdir build
cd build
cmake -G "Visual Studio 15 2017 Win64" -DUSE_DEBUGGER_BASED_SOLUTION=OFF ..
cmake --build . --config Release
After that, the resulting executable can be used to start any buggy command as follows:
suppress_wer <buggy_command> [buggy_args]
This disables the display of Windows Error Reporting dialogs when buggy_command
crashes.
Two alternative approaches to achieve the result are included in the gist. This section provides a quick overview of them.
This approach is based on this oldnewthing blog post. This is what gets used when executing the commands provided above. The idea is to change the way the system reacts to errors in the process using SetErrorMode
. Since error modes are inherited in child processes, crashes in the buggy child process do not display WER dialogs any more. See suppress_wer_set_error_mode.cpp
for details.
The approach can be easily adapted to any scripting language that supports interfacing with C, because it is actually all about executing a single WinAPI call to SetErrorMode
. For example, one can call the following function at the beginning of their Python script to disable WER for any subprocess:
def suppress_wer():
import ctypes
from ctypes import wintypes
SEM_NOGPFAULTERRORBOX = 2
kernel32 = ctypes.windll.kernel32
kernel32.SetErrorMode.restype = wintypes.UINT
kernel32.SetErrorMode.argtypes = [wintypes.UINT]
kernel32.SetErrorMode(SEM_NOGPFAULTERRORBOX)
This approach uses WinAPI Debugging Functions to monitor debug events in the child process and terminate it as soon as it is about to crash (on second-chance exception notifications). One can use this approach by setting -DUSE_DEBUGGER_BASED_SOLUTION=ON
in the CMake command above. This approach has the additional requirement that suppress_wer
is built using the same architecture as the buggy application that we want to start. However, it has the advantage that more control over the child process is possible. For example, the code can be extended to handle debug events as desired, and invoke code in the child process context when needed (e.g. call _set_abort_behavior(0, _WRITE_ABORT_MSG);
when the child process starts to disable MSVCRT debug error dialogs). See suppress_wer_debugger.cpp
for details.