These days, I spend quite some time in Microsoft's
Windows Error Reporting
forum, which is where
David Ching, who is a Microsoft MVP, posed
an interesting problem this week.
On Vista, Windows Error Reporting will create and transmit minidump files only if the WER
servers request them. At least this seems to be the default behavior which both David and I have
observed on Vista systems. David, however, wanted to make sure that whenever an application
crashes, a minidump file is generated which the user or tester can then send directly
to the developers of the application for analysis - even if Microsoft's WER servers
never actually request the minidumps, which, as far as I can tell, is the default
for applications which have not been explicitly registered with and mapped
at
Winqual.
My first idea was to force the system into queuing mode. When crash reports are queued,
minidumps are always generated and stored locally, so that they can be transmitted to
the error reporting server later on. Queuing is enabled by setting
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\ForceQueue
(
DWORD
) to 1. (See
WER Settings
for documentation on this and other WER-related registry keys.)
Crash report data will be stored in directories such as
c:\Users\someusername\AppData\Local\temp
and
C:\ProgramData\Microsoft\Windows\WER\ReportQueue
.
That works, but it also suppresses the WER UI, which isn't ideal either. Isn't
there some way to have the cake and eat it, too?
Let's see: A variation of the above approach is to disable the Internet connection before
the crash occurs. You'll get the dialogs, but WER won't be able to connect to the Microsoft
servers, and so it should then also queue the crash information. Alternatively,
and this is something that I have tried myself a few times, you could set
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\Windows Error Reporting\CorporateWERServer
(string) to the name of some non-existing system. When a crash occurs, WER will try
to contact that server, find that it's not responding, and then store all crash data
locally so that it can be re-sent when the connection is later established.
Or you could go all the way and actually install such a Corporate Error Reporting server
on one of your systems. Probably one of the best solutions, since this gives you
direct access to minidump files within your organization.
But this blog isn't about IT, it's about hacking and coding
Here's an idea
how David's goals could be accomplished without implementing a full-blown
crash handler:
And here's the demo code which demonstrate this technique:
// Demo program using SetUnhandledExceptionFilter() and
// MiniDumpWriteDump().
//
// Claus Brod, http://www.clausbrod.de/Blog
#include <windows.h>
#include <DbgHelp.h>
#pragma comment(lib, "DbgHelp.lib")
#include <stdio.h>
static LONG WINAPI myfilter(_EXCEPTION_POINTERS *exc_ptr)
{
static const char *minidumpFilename = "myminidump.mdmp";
HANDLE hDumpFile = CreateFile(minidumpFilename, GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hDumpFile != INVALID_HANDLE_VALUE) {
__try {
MINIDUMP_EXCEPTION_INFORMATION exceptionInfo;
exceptionInfo.ThreadId = GetCurrentThreadId();
exceptionInfo.ExceptionPointers = exc_ptr;
exceptionInfo.ClientPointers = false;
BOOL ret = MiniDumpWriteDump(GetCurrentProcess(),
GetCurrentProcessId(), hDumpFile, MiniDumpNormal, &exceptionInfo, NULL, NULL);
if (ret) {
printf("Minidump information has been written to %s.\n", minidumpFilename);
}
} __except(EXCEPTION_EXECUTE_HANDLER) { }
CloseHandle(hDumpFile);
}
return EXCEPTION_CONTINUE_SEARCH;
}
static int wedding_crasher(int *pp)
{
*pp = 42;
return 42;
}
int main(void)
{
SetUnhandledExceptionFilter(myfilter);
wedding_crasher(0);
return 0;
}
And finally, here's a
really weird idea from Dmitry Vostokov:
Resurrecting Dr. Watson on Vista If you're into exception handling and crash analysis, Dmitry's
http://www.dumpanalysis.org/ web site is a fantastic resource. This guy
lives
in an exception filter
to top