When an application has an unhandled exception or a system routine calls abort (e.g. strcpy_s with a buffer size too small) the system is left to deal with the mess. Usually part of the process is displaying a crash dialog to the user notifying them that the application has unexpectedly terminated, creating a crash dump file, and possibly checking with Microsoft for a solution if it’s a known problem. Sometimes however, you’d prefer that your application not crash in such an “in your face” manner, such as when you spawn child or helper processes as part of a larger system which can manage the process termination on its own. The first thing you should do is focus on making your application NOT crash in the first place!
However, there are times when things may be beyond your control (e.g. making calls to a third-party library that sometimes wigs out on you) or you just want it as a fail safe in case. You can use you own unhandled-exception handler for instance, to perform custom logging. There are several manners in which the system and the C-runtime can notify the user of an abnormal application termination. In order to suppress all of them, most of the time, I use the following routines:
You’ll note that I said most of the time because this method doesn’t guarantee that all of them will be suppressed. Other libraries you call could overwrite your handlers for one. Secondly, the /GS (Buffer Security Check) compiler flags causes the CRT to directly invoke Dr. Watson in the case of a buffer-overrun for security purposes. To prevent and detect other libraries from overwriting your exception filter, you can use API hooking. When it comes to the CRT directly calling Dr. Watson, this is by design and Microsoft has no plans of changing it.
Here’s the important parts of the source. The entire project is available here.
#include <stdio.h> #include <stdlib.h> #include <Windows.h> // Function Declarations void suppress_crash_handlers( void ); long WINAPI unhandled_exception_handler( EXCEPTION_POINTERS* p_exceptions ); int main( int argc, char* argv[] ) { // Suppress C4100 Warnings for unused parameters (void*)argc; (void*)argv; suppress_crash_handlers( ); abort( ); return -1; } void suppress_crash_handlers( ) { // Register our own unhandled exception handler // http://msdn.microsoft.com/en-us/library/ms680634(v=vs.85).aspx SetUnhandledExceptionFilter( unhandled_exception_handler ); // Minimize what notifications are made when an error occurs // http://msdn.microsoft.com/en-us/library/ms680621(v=vs.85).aspx SetErrorMode( SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX ); // When the app crashes, don't print the abort message and don't call Dr. Watson to make a crash dump. // http://msdn.microsoft.com/en-us/library/e631wekh(v=VS.100).aspx _set_abort_behavior( 0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT ); } long WINAPI unhandled_exception_handler( EXCEPTION_POINTERS* p_exceptions ) { // Suppress C4100 Warnings unused parameters required to match the // function signature of the API call. (void*)p_exceptions; // Throw any and all exceptions to the ground. return EXCEPTION_EXECUTE_HANDLER; }