Note: I'm not interested in disabling WER, I'm interested in crash scenarios where WER isn't launched although it should and Windows "silently" terminates an app.
On Windows XP, it is pretty trivial to write a C or C++ application (in user mode) that messes up its own address space in such a way that when an Access Violation (or other unhandled Win32 Exception) is finally raised, Windows XP will just silently terminate the process without informing the user at all:
...
void stackbreaker() {
printf("%s\n", __FUNCTION__);
// global/static buffer
static char buf[128] = "In a hole in the ground there lived a hobbit. And it burrowed through your stack. It even built a round door into you function.";
// Get address on the stack
char local;
char* stack = &local;
// nuke the stack:
memcpy(stack - 64, buf, sizeof(buf));
// Kaboom. No user defined unhandled exception filter will be called. Stack nuked.
// Process will terminate silently on Windows XP.
// But on Windows-7 you still get the WER dialog.
}
...
Calling the above function in a simple C++ project (in release mode -- watch out for those compiler optimizations when testing -- and not run under the debugger) will:
SetUnhandledExceptionFilter
What I am wondering now is whether - under Windows 7 - the WER mechanism has been implemented in a way that I always get an error dialog for a crash[a] in my application, or whether there exist process corruption scenarios even in Windows 7, that will prevent the WER dialog from popping up?
I'll add a bit of the reading up I did:
In the book Windows via C/C++ (5th ed by Richter, Nasarre) they describe what happens in a "Faulting Process" (p 711):
- Exception filters.
- ...
- ...
- kernel detects unhandled exception
- blocking ALPC call to Wer Service
- WER reporting kicks in.
- ...
Now, they point here is that Win7 does this differently than Windows XP (to quote this book p. 710:)
... Starting with Windows Vista, the
UnhandledExceptionFilter
function no longer sends an error report to MS' servers. Instead. The kernel detects that the exception is not handled by the user-mode thread (Step 4)...
So this would imply, that there is no way at all for a process to "crash" -- in Vista and above -- in a way that prevents WER kicking in. I'm trying to either confirm or refute this.
[a]: Obviously, a process can easily be "killed" without any trace by calling one of the various *exit
or terminate*
functions. The question is, if you can rule out such a termination reason, (how) is it possible to "crash" a user-mode process on Win7 in a way that would prevent the WER dialog from being displayed.
I took a look at my edition of Windows Internals, but it doesn't have a whole lot to say on the subject. In earlier versions, the windows error reporting routine took place in the context of the crashing thread. This means that if the stack is trashed (as in your example), it might not be able to run.
In Vista and later, it runs externally to the crashing thread. In addition, the kernel itself is responsible for notifying WER when a process crashes (through an advanced local procedure call).
According to Windows Internals, these changes fix the vanishing process problem. I can only take their word for that. Obviously, if the WER service is itself damaged (or stopped), you'll still get silent crashes.
EDIT
From Windows Internals, 5th Edition, page 122:
Until Windows Vista, all the [WER] operations we've described had to occur within the crashing thread's context... In certain types of crashes ... the unhandled exception filter itself crashed. This "silent process death" was not logged anywhere. ... Windows Vista and later versions improved the WER mechanism by performing this work externally from the crashed thread, if the unhandled exception filter itself crashes.
Page 124:
...all Windows processes now have an error port that is actually an ALPC port object registered by the WER service. The kernel ... will use this port to send a message to the WER service, which will then analyze the crashing process. ... This solves all the problems of silent process death...
You already know how to crash a process, so I answer regarding hiding the WER dialog.
Way to hide WER dialog since Windows XP:
UINT WINAPI SetErrorMode(_In_ UINT uMode);
SEM_NOGPFAULTERRORBOX 0x0002 The system does not display the Windows Error Reporting dialog.
Note that there are also other reasons for error dialogs and they can be disabled with this function too, check the documentation for more info.
Additionally since Windows 7:
BOOL SetThreadErrorMode(
_In_ DWORD dwNewMode,
_Out_ LPDWORD lpOldMode
);
Some programs and dll-s use these functions to hide errors from the user.
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