{"id":13273,"date":"2010-07-30T07:00:00","date_gmt":"2010-07-30T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2010\/07\/30\/decoding-the-parameters-of-a-thrown-c-exception-0xe06d7363\/"},"modified":"2020-12-30T21:30:05","modified_gmt":"2020-12-31T05:30:05","slug":"20100730-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20100730-00\/?p=13273","title":{"rendered":"Decoding the parameters of a thrown C++ exception (0xE06D7363)"},"content":{"rendered":"<p><i>Special preview content for <a title=\"I will be speaking at TechReady11\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20100722-01\/?p=13353\"> my TechReady talk later today<\/a>. I&#8217;d like to claim it was planned this way, but actually it was just a coincidence. <\/i><\/p>\n<p>The Visual C++ compiler uses exception code <code>0xE06D7363<\/code> for C++ exceptions. Here&#8217;s how you can decode the other parameters. (Handy if you&#8217;re debugging a crash dump.)<\/p>\n<p>Note that this information falls under the category of implementation detail. There is no guarantee that this method will continue to work in the future, so don&#8217;t write code that relies on it. It&#8217;s just a debugging tip.<\/p>\n<p>When the C++ exception is raised, <a title=\"PRB: Exception Code 0xE06D7363 When Calling Win32 SEH APIs\" href=\"http:\/\/web.archive.org\/web\/20070501045100\/http:\/\/support.microsoft.com\/kb\/185294\"> the exception code is 0xE06D7363<\/a> and there are three (possibly four) parameters.<\/p>\n<ul>\n<li>Parameter\u00a00 is some internal value not important to the discussion.<\/li>\n<li>Parameter\u00a01 is a pointer to the object being thrown (sort of).<\/li>\n<li>Parameter\u00a02 is a pointer to information that describes the object being thrown.<\/li>\n<li>Parameter\u00a03 is the <code>HINSTANCE<\/code> of the DLL that raised the exception. (Present only on 64-bit Windows.)<\/li>\n<\/ul>\n<p>The object being thrown is pretty much the object being thrown, except that sometimes there is some junk in front that you have to skip over. Once you figure out what it is, you can dump it. (I haven&#8217;t bothered trying to figure out exactly how much; I just dump bytes and figure out the correct start of the object by inspection.) But what is it? That&#8217;s what Parameter\u00a02 tells you, but in a very roundabout way.<\/p>\n<p>Take Parameter\u00a02 and go to the fourth <code>DWORD<\/code> and treat it as a pointer. (On 64-bit systems, you have to add this value to the <code>HINSTANCE<\/code> passed as Parameter\u00a03 to convert it to a pointer.)<\/p>\n<p>Next, go to the second <code>DWORD<\/code> and treat it as a pointer. (Again, on 64-bit systems, it&#8217;s really an offset from the <code>HINSTANCE<\/code>.)<\/p>\n<p>Next, go to the second <code>DWORD<\/code> and treat it as a pointer. (64-bit systems: you know the drill.)<\/p>\n<p>Finally, skip over the first two <code>void*<\/code>s and the rest is the class name.<\/p>\n<p>Here&#8217;s a picture, rendered in high-tech ASCII line drawing. Pointer-sized fields are marked with an asterisk, and fields whose value are unknown or not important are marked with tildes.<\/p>\n<pre>EXCEPTION_RECORD\r\n+----------+\r\n| E06D7363 |\r\n+----------+\r\n|  ~~~     |\r\n+----------+\r\n|* ~~~     |\r\n+----------+\r\n|* ~~~     |\r\n+----------+\r\n| 3 or 4   |\r\n+----------+\r\n|* ~~~     |\r\n+----------+\r\n|*Object   |\r\n+----------+     +---+\r\n|*       ------&gt; |~~~|\r\n+----------+     +---+\r\n|*HINSTANCE|     |~~~|\r\n+----------+     +---+\r\n                 |~~~|\r\n                 +---+    +---+\r\n                 | -----&gt; |~~~|\r\n                 +---+    +---+    +---+\r\n                          | -----&gt; |~~~|\r\n                          +---+    +---+    +----------+\r\n                                   | -----&gt; |*   ~~~   |\r\n                                   +---+    +----------+\r\n                                            |*   ~~~   |\r\n                                            +----------+\r\n                                            |Class name|\r\n                                            +----------+\r\n<\/pre>\n<p>&#8220;When in doubt, add another level of indirection&#8221; appears to be the mantra here.<\/p>\n<p>Here&#8217;s a real-world example I had to debug. This came from a crash dump in a third-party application reported via Windows Error Reporting, so all debugging has to be done without source code or symbols.<\/p>\n<pre>0:008&gt; .exr <a title=\"Sucking the exception pointers out of a stack trace\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20060821-17\/?p=30033\">00000000`015dede0<\/a>\r\nExceptionAddress: 000007fefd23bb5d (KERNEL32!RaiseException+0x39)\r\n   ExceptionCode: e06d7363 (C++ EH exception)\r\n  ExceptionFlags: 00000001\r\nNumberParameters: 4 \/\/ this is running on 64-bit Windows\r\n   Parameter[0]: 0000000019930520\r\n   Parameter[1]: 00000000015def30 \/\/ object being thrown\r\n   Parameter[2]: 00000000100cefa8 \/\/ magic Parameter 2\r\n   Parameter[3]: 0000000010000000 \/\/ HINSTANCE\r\n<\/pre>\n<p>According to the cookbook, we follow Parameter\u00a02:<\/p>\n<pre>0:008&gt; dd 00000000100cefa8 l4\r\n00000000`100cefa8  00000000 00000000 00000000 000cefc8\r\n                                              ^^^^^^^^\r\n<\/pre>\n<p>and take the fourth <code>DWORD<\/code>. Since this is a 64-bit machine, we add it to the <code>HINSTANCE<\/code> before dumping. (If this were a 32-bit machine, we would just dump it directly.)<\/p>\n<pre>0:008&gt; dd 100cefc8 l2\r\n00000000`100cefc8  00000005 000ceff8\r\n                            ^^^^^^^^\r\n<\/pre>\n<p>Now we take the second <code>DWORD<\/code> (add the <code>HINSTANCE<\/code> since this is a 64-bit machine) and then dump it again:<\/p>\n<pre>0:008&gt; dd 100ceff8 l2\r\n00000000`100ceff8  00000001 000d6670\r\n                            ^^^^^^^^\r\n<\/pre>\n<p>Okay, we&#8217;re within striking distance now. Since this is a 64-bit machine, we add the <code>HINSTANCE<\/code> to the offset. And on all platforms, we add two pointers (which is 0x10 on a 64-bit machine and 8 on a 32-bit machine). The result should be an ASCII string representing the class name:<\/p>\n<pre>0:008&gt; da 100d6670+10\r\n00000000`100d6680  \".PEAVCResourceException@@\"\r\n<\/pre>\n<p>If you ignore the decorations, you see that this is telling you that the object thrown was a <code>CResource\u00adException<\/code>.<\/p>\n<p>And for old time&#8217;s sake, here&#8217;s a 32-bit version I just made up now.<\/p>\n<pre>0:000&gt; .exr 0008f2e4\r\nExceptionAddress: 7671b046 (kernel32!RaiseException)\r\n   ExceptionCode: e06d7363 (C++ EH exception)\r\n  ExceptionFlags: 00000001\r\nNumberParameters: 3 \/\/ 32-bit platform\r\n   Parameter[0]: 19930520\r\n   Parameter[1]: 0008f384 \/\/ object being thrown\r\n   Parameter[2]: 10cfed60 \/\/ magic Parameter 2\r\n0:000&gt; dd 10cfed60 l4\r\n10cfed60  00000000 00000000 00000000 10db297c\r\n0:000&gt; dd 10db297c l2\r\n10db297c  00000004 10db2990\r\n0:000&gt; dd 10db2990 l2\r\n10db2990  00000001 10dbccac\r\n0:000&gt; da 10dbccac+8\r\n10dbccb4  \".PAVCFileException@@\"\r\n<\/pre>\n<p>Anyway, back to the original problem: Knowing that the object being thrown was a <code>CResource\u00adException<\/code> was a big help, because that&#8217;s a class used by MFC, so I have additional information as to what it does and how it&#8217;s used. This turns out to have been the necessary foothold to identify the source of the problem, which will be <a title=\"Using the wrong HINSTANCE in RegisterClass is like identity theft\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20110715-00\/?p=10133\"> the subject of a future write-up<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Start with the 0xE06D7363&#8230;<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-13273","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Start with the 0xE06D7363&#8230;<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/13273","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=13273"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/13273\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=13273"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=13273"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=13273"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}