Edit
Attach
Printable
topic end
<!-- * Set TOPICTITLE = #define private public - The end is nigh (for my process) (16 Jun 2007) --> <style type="text/css"> pre {background-color:#ffeecc;} </style> %STARTINCLUDE% <a name="16"></a> ---+++ [[DefinePrivatePublic20070616][The end is nigh (for my process)]] (16 Jun 2007) <summary>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. </summary> <img src="%ATTACHURLPATH%/reportfault_xp.jpg" alt="reportfault_xp.jpg" align="right" /> In fact, this is pretty much what [[http://msdn2.microsoft.com/en-us/library/ms681662.aspx][Windows Error Reporting]] is all about, only that the crash reports are sent to Microsoft first (to their [[http://winqual.microsoft.com][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 [[http://msdn2.microsoft.com/en-us/library/ms680574.aspx][<nop>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 [[http://msdn2.microsoft.com/en-us/library/7sw7cha4(VS.80).aspx][exception filter]], and you're done. The required code is pretty trivial and looks roughly like this: <pre> <font color="#2e8b57"><b>int</b></font> filter_exception(EXCEPTION_POINTERS *exc_ptr) { EFaultRepRetVal repret = ReportFault(exc_ptr, 0); <font color="#804040"><b>switch</b></font> (repret) { <font color="#0000ff">// decode return value...</font> <font color="#0000ff">//</font> } <font color="#804040"><b>return</b></font> EXCEPTION_EXECUTE_HANDLER; } <font color="#2e8b57"><b>void</b></font> main(<font color="#2e8b57"><b>void</b></font>) { __try { <font color="#2e8b57"><b>int</b></font> *foo = (<font color="#2e8b57"><b>int</b></font> *)<font color="#ff00ff">0</font>; *foo = <font color="#ff00ff">42</font>; } __except(filter_exception(GetExceptionInformation())) { _tprintf(__T(<font color="#ff00ff">"Nothing to see here, move on, process is still alive!</font><font color="#6a5acd">\n</font><font color="#ff00ff">"</font>)); } Sleep(<font color="#ff00ff">5000</font>); } </pre> Sequence of events: * A structured exception block is established using =__try= and =__except=. * Code provokes an access violation. * The exception _filter_ =filter_exception= is consulted by the exception handling infrastructure to find out how to proceed with the exception. * The filter calls =ReportFault= to 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_HANDLER= to 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. <img src="%ATTACHURLPATH%/reportfault_vista.jpg" alt="reportfault_vista.jpg" align="right" /> 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. =ReportFault= never really returns to the caller! I debugged into =ReportFault= on my Vista machine and found that =ReportFault= spawns off a process called =wermgr.exe= which performs the actual work. My current hypothesis is that it is =wermgr.exe= which terminates the calling process if the user chooses "Close program". If you want to try it yourself, click [[%ATTACHURL%/reportfault.cpp][here]] to download the demo code. To compile, simply run it through =cl.exe=: <pre> cl.exe reportfault.cpp </pre> Now, can we complain about this, really? After all, you can't call it surprising if a program closes after hitting the "Close program" button. Still, the behavior differs from the old XP dialog - and it is inconsistent even on Vista. 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 configured in the "Problem Reports and Solutions" control panel: <img src="%ATTACHURLPATH%/vista_settings.jpg" alt="vista_settings.jpg" width="600" height="253" border="1" /> <br clear="all" /> After changing the report settings as shown above ("Ask me") and then running the test application again, the error reporting dialog looks like this: <img src="%ATTACHURLPATH%/reportfault_vista_ask.jpg" alt="reportfault_vista_ask.jpg" width="528" height="281" /> <br clear="all" /> When I click on "Close program" _now_, guess what happens - 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... 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 in my application, or I could add my own special reporting. Or call the cops. =ReportFault= won't let me do 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. --- %STOPINCLUDE% %COMMENT{type="below" nonotify="on"}% ---
to top
End of topic
Skip to action links
|
Back to top
Edit
|
Attach image or document
|
Printable version
|
Raw text
|
Refresh
|
More topic actions
Revisions: | r1.3 |
>
|
r1.2
|
>
|
r1.1
|
Total page history
|
Backlinks
You are here:
Blog
>
DefinePrivatePublic20070616
r1.3 - 20 Sep 2007 - 06:14 -
ClausBrod
to top
Blog
This site
2017
:
12
-
11
-
10
2016
:
10
-
7
-
3
2015
:
11
-
10
-
9
-
4
-
1
2014
:
5
2013
:
9
-
8
-
7
-
6
-
5
2012
:
2
-
10
2011
:
1
-
8
-
9
-
10
-
12
2010
:
11
-
10
-
9
-
4
2009
:
11
-
9
-
8
-
7
-
6
-
5
-
4
-
3
2008
:
5
-
4
-
3
-
1
2007:
12
-
8
-
7
-
6
-
5
-
4
-
3
-
1
2006:
4
-
3
-
2
-
1
2005:
12
-
6
-
5
-
4
2004:
12
-
11
-
10
C++
CoCreate Modeling
COM & .NET
Java
Mac
Lisp
OpenSource
Scripting
Windows
Stuff
Changes
Index
Search
Maintenance
Impressum
Datenschutzerklärung
Home
Webs
Atari
Blog
Claus
CoCreateModeling
Klassentreffen
Main
Sandbox
Sommelier
TWiki
Xplm
Jump:
Copyright © 1999-2024 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki?
Send feedback