How can you tell that you're the control freak type of Windows programmer?
Easy: You feel that irresistible urge to install top-level exception handlers which 
report application crashes to the end user and provide useful options on how to 
proceed, such as to report the issue to the software vendor, save the currently 
loaded data, inspect the issue in more detail, or call the police.

In fact, this is pretty much what 
Windows Error Reporting
is all about, only that the crash reports are sent to Microsoft
first (to their 
Winqual site, that is), from where
ISVs can then download them for further analysis. Oh, and the other difference is that
Microsoft dropped the "call the police" feature in order to get Vista done in time.
One of the applications that I'm working on already had its own top-level crash handler
which performed some of the services also provided by Windows Error Reporting. It 
was about time to investigate Microsoft's offerings in this area and see how they 
can replace or augment the existing crash handler code.
The first option I looked at was the 
ReportFault
API. Microsoft's documentation says that the function is obsolete, and we should rather use a different
set of APIs collectively called the "WER functions". However, understanding them requires a lot more
brain calories than the trivial 
ReportFault call which you can simply drop into an
exception filter,
and you're done.
The required code is pretty trivial and looks roughly like this:
int filter_exception(EXCEPTION_POINTERS *exc_ptr)
{
  EFaultRepRetVal repret = ReportFault(exc_ptr, 0);
  switch (repret)
  {
         // decode return value...
         //
  }
  return ret;
  return EXCEPTION_EXECUTE_HANDLER;
}
void main(void)
{
  __try {
    int *foo = (int *)0;
    *foo = 42;
  } __except(filter_exception(GetExceptionInformation())) {
    _tprintf(__T("Nothing to see here, move on, process is still alive!\n"));
  }
  Sleep(5000);
}
Sequence of events:
-  A structured exception block is established using __tryand__except.
-  Code provokes an access violation.
-  The exception filter filter_exceptionis consulted by the exception
     handling infrastructure to find out how to proceed with the exception.
-  The filter calls ReportFaultto display the crash dialog as shown above,
     and to give the user options to debug the problem, ignore it, or report
     it to Microsoft.
-  After performing its menial reporting duties, the exception filter
     returns EXCEPTION_EXECUTE_HANDLERto indicate that its associated
     exception handler should be called.
That exception handler is, in fact, essentially the 
_tprintf statement
which spreads the good news about the process still being alive.

On XP, that is. On Vista, the 
_tprintf statement may actually never execute.
You'll still get a nice reporting dialog, such as the one in the screenshot
to the right, but when you click the "Close program" button, the calling process
will be terminated immediately, i.e. the call to 
ReportFault never really
returns to the caller!
I debugged into 
ReportFault and found that it spawns off a process called
wermgr.exe which performs the actual work. My current hypothesis is that
it is that 
wermgr.exe process which terminates the calling process
if the user chooses "Close program".
If you want to try it yourself, click 
here
to download the demo code. To compile, simply run it through 
cl.exe:
  cl.exe reportfault.cpp
Now, I can't really complain - the fact that a program is closed after
hitting the "Close program" button is hardly surprising.
Still, the behavior differs from the old XP dialog. Worse, it is in fact inconsistent.
What I just described is the behavior that I found with the default
error reporting settings in Vista. By default, Vista "checks for solutions
automatically" and doesn't ask the user what to do when a crash occurs.
This can be changed in the "Problem Reports and Solutions" control panel:
 
After changing the report settings as shown above ("Ask me"), the error reporting
dialog looks like this:
 
And when I click on "Close program" 
now, guess what - the process does 
not terminate,
and the 
_tprintf statement in my exception handler is executed, just like on XP.
So that "Close program" button can mean two different things on Vista!
But it's not just this inconsistency which bugged me. I also don't like the idea of 
letting the error reporting dialog pull the rug from under my feet. Sure, I'd like to 
use the dialog's services, but when it returns, I want to 
make my 
own decisions about how to proceed. For example, I could try and save the 
currently loaded data, or I could add my own special 
reporting. Or call the police.
But 
ReportFault won't let me do all that on Vista. And so I set out to
burn those extra brain calories anyway and learn about the new WER APIs 
which were introduced with Windows Vista.
And burn calories I did, oh yes. More on this hopefully soon.
to top