Edit
Attach
Printable
topic end
<!-- * Set TOPICTITLE = #define private public - Crashing with style on Vista (18 Jun 2007) --> <style type="text/css"> pre {background-color:#ffeecc;} </style> %STARTINCLUDE% <a name="18"></a> ---+++ [[DefinePrivatePublic20070618][Crashing with style on Vista]] (18 Jun 2007) <summary>A few days ago, I reported about the [[Blog.DefinePrivatePublic20070616][peculiarities of the <nop>ReportFault]] API, particularly on Windows Vista, and how those peculiarities drove me to give in to Microsoft's sound advice and use the new and shiny [[http://msdn2.microsoft.com/en-us/library/ms681662.aspx][Windows Error Reporting (WER) APIs]] on Vista.</summary> [[http://msdn2.microsoft.com/en-us/library/ms680574][<nop>ReportFault()]] is a great one-stop shopping API: A one-liner will display all required dialogs, ask the user if he wants to contact Microsoft, create report data (including [[http://msdn2.microsoft.com/en-us/library/ms680369.aspx][minidumps]]) if required, and send the whole report off to Microsoft. The new [[http://msdn2.microsoft.com/en-us/library/ms681662.aspx][WER APIs]] in Vista are slightly more complex, but also provide more control for the details of error reporting. Well, if you know how to handle the APIs, that is. Apparently, I do _not_ know how to handle them since I still haven't solved all the problems around them. More on this in a moment. Let's first take a look at the core of a test application I wrote: <pre> <font color="#2e8b57"><b>static</b></font> <font color="#2e8b57"><b>bool</b></font> report_crash(_EXCEPTION_POINTERS *inExceptionPointer) { <font color="#0000ff">// Set up parameters for WerReportCreate()</font> WER_REPORT_INFORMATION werReportInfo; memset(&werReportInfo, <font color="#ff00ff">0</font>, <font color="#804040"><b>sizeof</b></font>(werReportInfo)); werReportInfo.dwSize = <font color="#804040"><b>sizeof</b></font>(werReportInfo); wcscpy_s(werReportInfo.wzFriendlyEventName, _countof(werReportInfo.wzFriendlyEventName), <font color="#ff00ff">L"werapitest (friendly event name)"</font>); wcscpy_s(werReportInfo.wzApplicationName, _countof(werReportInfo.wzApplicationName), <font color="#ff00ff">L""</font>); wcscpy_s(werReportInfo.wzDescription, _countof(werReportInfo.wzDescription), <font color="#ff00ff">L"Critical runtime problem"</font>); PCWSTR eventType = <font color="#ff00ff">L"werapitest (eventType)"</font>; <font color="#0000ff">// APPCRASH</font> HREPORT hReportHandle; <font color="#804040"><b>if</b></font> (FAILED(pWerReportCreate(eventType, WerReportCritical, &werReportInfo, &hReportHandle)) || !hReportHandle) { <font color="#804040"><b>return</b></font> <font color="#ff00ff">false</font>; } <font color="#2e8b57"><b>bool</b></font> ret = <font color="#ff00ff">false</font>; WER_EXCEPTION_INFORMATION werExceptionInformation; werExceptionInformation.bClientPointers = FALSE; werExceptionInformation.pExceptionPointers = inExceptionPointer; <font color="#2e8b57"><b>bool</b></font> dumpAdded = SUCCEEDED(pWerReportAddDump(hReportHandle, ::GetCurrentProcess(), ::GetCurrentThread(), WerDumpTypeMiniDump, &werExceptionInformation, <font color="#ff00ff">NULL</font>, <font color="#ff00ff">0</font>)); <font color="#804040"><b>if</b></font> (!dumpAdded) { FATAL_ERROR(<font color="#ff00ff">"Minidump generation failed.</font><font color="#6a5acd">\n</font><font color="#ff00ff">"</font>); } DWORD submitOptions = WER_SUBMIT_OUTOFPROCESS | WER_SUBMIT_NO_CLOSE_UI; WER_SUBMIT_RESULT submitResult; <font color="#804040"><b>if</b></font> (SUCCEEDED(pWerReportSubmit(hReportHandle, WerConsentNotAsked, submitOptions, &submitResult))) { <font color="#804040"><b>switch</b></font>(submitResult) { <font color="#0000ff">// ... decode result ...</font> } } pWerReportCloseHandle(hReportHandle); <font color="#804040"><b>return</b></font> ret; } <font color="#2e8b57"><b>static</b></font> <font color="#2e8b57"><b>int</b></font> filter_exception(EXCEPTION_POINTERS *exc_ptr) { report_crash(exc_ptr); <font color="#804040"><b>return</b></font> EXCEPTION_EXECUTE_HANDLER; } <font color="#2e8b57"><b>static</b></font> <font color="#2e8b57"><b>void</b></font> wedding_crasher(<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())) { printf(<font color="#ff00ff">"Now in exception handler, process is still alive!</font><font color="#6a5acd">\n</font><font color="#ff00ff">"</font>); } Sleep(<font color="#ff00ff">5000</font>); } <font color="#2e8b57"><b>int</b></font> main() { HMODULE hWer = LoadLibrary(<font color="#ff00ff">"Wer.dll"</font>); <font color="#804040"><b>if</b></font> (hWer) { pWerReportCreate = (pfn_WERREPORTCREATE)GetProcAddress(hWer, <font color="#ff00ff">"WerReportCreate"</font>); pWerReportSubmit = (pfn_WERREPORTSUBMIT)GetProcAddress(hWer, <font color="#ff00ff">"WerReportSubmit"</font>); pWerReportCloseHandle = (pfn_WERREPORTCLOSEHANDLE)GetProcAddress(hWer, <font color="#ff00ff">"WerReportCloseHandle"</font>); pWerReportAddDump = (pfn_WERREPORTADDDUMP)GetProcAddress(hWer, <font color="#ff00ff">"WerReportAddDump"</font>); } <font color="#804040"><b>if</b></font> (!pWerReportCreate || !pWerReportSubmit || !pWerReportCloseHandle || !pWerReportAddDump) { printf(<font color="#ff00ff">"Cannot initialize WER API.</font><font color="#6a5acd">\n</font><font color="#ff00ff">"</font>); <font color="#804040"><b>return</b></font> <font color="#ff00ff">1</font>; } wedding_crasher(); <font color="#804040"><b>return</b></font> <font color="#ff00ff">0</font>; } </pre> The fundamental approach is still the same as for the =ReportFault= test program [[DefinePrivatePublic20070616][presented recently]]: * 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 the WER APIs to display the crash dialog(s), and to give the user options to debug the problem, ignore it, or report it to Microsoft. * The exception filter returns =EXCEPTION_EXECUTE_HANDLER= to indicate that its associated exception handler should be called. The following WER APIs are used to create and send a crash report: * [[http://msdn2.microsoft.com/en-us/library/ms681640.aspx][<nop>WerReportCreate]] to open a handle for a new crash report * [[http://msdn2.microsoft.com/en-us/library/ms681636.aspx][<nop>WerReportAddDump]] to add minidump data to the report * [[http://msdn2.microsoft.com/en-us/library/ms681644.aspx][<nop>WerReportSubmit]] to display the WER dialogs and (if the user chooses this option) to send the report to Microsoft * [[http://msdn2.microsoft.com/en-us/library/ms681639.aspx][<nop>WerReportCloseHandle]] to release resources associated with the crash report. The WER APIs do indeed solve a problem that I found with =ReportFault= on Vista: They don't force the calling process to be terminated, and allow me to proceed as I see fit. That's really good news. The problem I haven't resolved yet is this: Even though I call =WerReportAddDump=, I have no idea whether minidump data are actually generated and sent. In fact, from the feedback provided by the system, it seems likely that those data are _not_ generated. To illustrate my uncertainties, I wrote a test program called =werapitest=. The code is attached as a ZIP file; unpack it into a directory, open a Visual Studio command prompt window, and build the code as follows: <pre> cl werapitest.cpp </pre> Run the resulting executable, then open up the "Problem Reports and Solutions" control panel and click on "View problem history". On my system, I get something like this: <img src="%ATTACHURLPATH%/werapitest_history.jpg" alt="werapitest_history.jpg" /> <br clear="all" /> Double-clicking on the report entry leads to this: <img src="%ATTACHURLPATH%/werapitest_entry.png" alt="werapitest_entry.png" /> <br clear="all" /> The problem history entry does not mention any attached files, such as minidump data! When a crash occurs, the system also writes entries into the event log; those log entries claim there _are_ additional data in paths such as =C:\Users\clausb\AppData\Local\Microsoft\Windows\WER\ReportArchive\Report0f8918ad=, and indeed, such directories exist and each contain a file called =Report.wer=, which holds data such as: <pre> Version=1 EventType=werapitest (eventType) EventTime=128266502225896608 ReportType=1 Consent=1 UploadTime=128266502257542112 Response.BucketId=8 Response.BucketTable=5 Response.type=4 DynamicSig[1].Name=OS Version DynamicSig[1].Value=6.0.6000.2.0.0.256.16 DynamicSig[2].Name=Locale ID DynamicSig[2].Value=1033 UI[3]=werapitest.exe has stopped working UI[4]=Windows can check online for a solution to the problem. UI[5]=Check online for a solution and close the program UI[6]=Check online for a solution later and close the program UI[7]=Close the program State[0].Key=Transport.DoneStage1 State[0].Value=1 State[1].Key=DataRequest State[1].Value=Bucket=8/nBucketTable=5/nResponse=1/n FriendlyEventName=werapitest (friendly event name) ConsentKey=werapitest (eventType) AppName=werapitest.exe AppPath=C:\tmp\werapitest.exe ReportDescription=Critical runtime problem </pre> So again, the minidump is not mentioned anywhere. Now let's try some minimal code which uses neither =ReportFault= nor the new WER API: <pre> int main(void) { int *p = (int *)0; *p = 42; return 0; } </pre> After running this code and letting it crash and report to Microsoft, I get the following problem history entry: <img src="%ATTACHURLPATH%/crashme.jpg" alt="crashme.jpg" width="710" height="527" /> <br clear="all" /> This problem report contains a _lot_ more data than the one for =werapitest=, and it even refers to a minidump file which was apparently generated by the system and probably also sent to Microsoft. So the lazy code which doesn't do anything about crashes gets full and proper service from the OS, while the application which tries to deal with a crash in an orderly manner and elaborately goes through all the trouble of using the proper APIs doesn't get its message across to Microsoft. I call this unfair ;) Oh, and in case you're wondering: Yes, we've registered with Microsoft's Winqual site where the crash reports are supposed to be sent to, and we established "product mappings" there, and the whole process seems to work for XP clients just fine. I'm pretty sure that I'm just missing a couple of details with the new APIs, or maybe I'm misinterpreting the feedback from the system. I ran numerous experiments and umpteen variations, I've searched the web high and low, read the docs, consulted newsgroups [[http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=1429&SiteID=1][here]] and [[http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=904&SiteID=1][there]] - and now I'm running out of ideas. Any hints most welcome... <i>PS: I did indeed receive some hints. For updated WER code, along with an explanation on why the above failed, see [[DefinePrivatePublic20070625][Crashing with style on Vista, part II]].</i> --- %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.6 |
>
|
r1.5
|
>
|
r1.4
|
Total page history
|
Backlinks
You are here:
Blog
>
DefinePrivatePublic20070618
r1.6 - 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