First I will describe the crash types I know about. Scroll down for the actual question. Note that I am only interested in crashes that are handled by Windows. Specific applications and frameworks sometimes have their own crash handlers (eg. Cygwin, the VCL, Java or .NET), which I will not discuss.
On Windows XP, most unhandled "Structured Exceptions" such as access violations produce a Microsoft Application Error Reporting dialog (it was later renamed "Windows Error Reporting" but the executable is dwwin.exe
and I will call it Dr Watson):
It is easily reproduced with *(char*)0=0;
Calling FatalAppExit()
produces a MessageBox and Event Log entry, but no Dr Watson:
On Windows XP a stack overflow causes the process to unceremoniously exit with no notification at all. (I think this was fixed starting with Vista)
It can be reproduced with main(){main();}
This dialog is owned by csrss.exe
, and by the time I see it, the AcroRd32.exe
process has exited.
It also writes an entry in the System Event Log (which a Dr Watson crash doesn't do):
I can reproduce the dialog and Event Log entry (but obviously not an actual crash), with this call to MessageBox:
MessageBox(
0,
"The exception unknown software exception (0xc0000409) occurred in the application at location 0x00404def.",
"AcroRd32.exe - Application Error",
MB_ICONSTOP | MB_SERVICE_NOTIFICATION);
I've ruled out Adobe Reader running as a service. It is version 11.0.08. The crash seems to happen sporadically when a Windows Explorer window with a PDF file selected becomes the active window.
Of course I'm not asking you to troubleshoot Adobe Reader for me, just how to produce an "Application Error" / "Application Popup" type of crash, preferably programmatically so I can understand what's going on.
This looks like the work of kernel32.UnhandledExceptionFilter
. You might be able to trigger this error message with:
EXCEPTION_RECORD Rec = {
ExceptionCode : 0xc0000409, /* STATUS_STACK_BUFFER_OVERRUN */
ExceptionAddress : cast(void*) 0x404def,
};
CONTEXT Ctx;
RtlCaptureContext(&Ctx);
EXCEPTION_POINTERS Xcep = {
ExceptionRecord : &Rec,
ContextRecord : &Ctx,
};
UnhandledExceptionFilter(&Xcep);
However on Windows 7 that didn't do it for me, it just went straight to Dr Watson.
What does seem to work on W7 is this:
size_t[2] Params = [
0xc0000409, /* STATUS_STACK_BUFFER_OVERRUN */
0x404def, /* exception address */
];
int Response;
NtRaiseHardError(
0xc0000144 /* STATUS_UNHANDLED_EXCEPTION */ |
0x10000000 /* HARDERROR_OVERRIDE_ERRORMODE */,
Params.length,
0, /* UnicodeStringParameterMask */
Params.ptr,
2 /* OptionOkCancel */,
&Response
);
I know UnhandledExceptionFilter
has this code somewhere, I just don't know what conditions it needs to take that code path. But you can just call NtRaiseHardError
like this yourself.
Here's the result:
I don't use XP any more so you'll have to experiment yourself to see how these methods behave on XP, but hopefully this will give you a starting point.
The error dialog owned by CSRSS (which can also be programmatically triggered by a manual call to NtRaiseHardError, see this answer), is displayed on Windows when you have an unhandled exception. For all Win32 applications, a default exception handler for unhandled exceptions is set up by kernel32.dll, and this is this handler that does the job of either showing the Windows Error Reporting dialog, or showing the error dialog.
For the details, the open-source ReactOS project (which aim is to "re-create" Windows in an open-source way using clean-room RE) has similar code, that should help you knowing precisely in which conditions the error dialog appears: see the UnhandledExceptionFilter() function in dll/win32/kernel32/client/except.c.
User contributions licensed under CC BY-SA 3.0