{"id":30033,"date":"2006-08-21T10:00:17","date_gmt":"2006-08-21T10:00:17","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2006\/08\/21\/sucking-the-exception-pointers-out-of-a-stack-trace\/"},"modified":"2006-08-21T10:00:17","modified_gmt":"2006-08-21T10:00:17","slug":"sucking-the-exception-pointers-out-of-a-stack-trace","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20060821-17\/?p=30033","title":{"rendered":"Sucking the exception pointers out of a stack trace"},"content":{"rendered":"<p>\nOften, you find yourself staring at a stack trace for a caught exception\nand want to see the original exception.\n<\/p>\n<pre>\nChildEBP RetAddr  Args to Child\n030c21d0 76df3448 00000000 030c6138 76db6b0d ntdll!DbgBreakPoint\n030c21dc 76db6b0d 030c2204 77b8d585 030c220c ole32!PeekMessageExceptionFilter+0x42\n030c21e4 77b8d585 030c220c 00000000 030c220c ole32!CCliModalLoop::MyPeekMessage+0x41\n030c220c 77f36992 030c25d0 030c6128 030c22e8 msvcrt!_except_handler3+0x61\n030c2230 77f36964 030c25d0 030c6128 030c22e8 ntdll!ExecuteHandler2+0x26\n030c22d8 77f36884 030c1000 030c22e8 00010007 ntdll!ExecuteHandler+0x24\n030c25b8 77f6e0dd 030c25d0 00000000 00000000 ntdll!RtlRaiseException+0x3d\n030c262c 77d3c239 77d4a4b6 77d3e2c5 030c3767 ntdll!RtlDeactivateActivationContextUnsafeFast+0x233\n030c2630 77d4a4b6 77d3e2c5 030c3767 030c26a0 USER32!UserCallWinProcCheckWow+0x167\n030c2634 77d3e2c5 030c3767 030c26a0 77d4a46f USER32!_NLG_Return2\n030c265c 77d3e288 030c57b4 ffffffff 030c2688 USER32!__local_unwind2+0x70\n030c2688 77f36992 030c26f8 030c57b4 030c27a4 USER32!_except_handler3+0xd5\n030c26ac 77f36964 030c26f8 030c57b4 030c27a4 ntdll!ExecuteHandler2+0x26\n030c2a74 77b8d36d 030c6128 77b8d36d 00000000 ntdll!ExecuteHandler+0x24\n030c2a9c 77b8d59d 030c6128 030c2ac0 00000000 msvcrt!__global_unwind2+0x18\n030c2ac0 77f36992 030c2ba4 030c6128 030c2bc0 msvcrt!_except_handler3+0x75\n030c2ae4 77f36964 030c2ba4 030c6128 030c2bc0 ntdll!ExecuteHandler2+0x26\n030c2b8c 77f36796 030c1000 030c2bc0 030c2ba4 ntdll!ExecuteHandler+0x24\n030c2b8c 77b7aa54 030c1000 030c2bc0 030c2ba4 ntdll!KiUserExceptionDispatcher+0xe\n030c3300 77b7b4dc 030c3324 7715b1b4 00000000 msvcrt!_woutput_l+0x18\n<\/pre>\n<p>\n(You too can get symbols for operating system binaries,\neither by using\n<a HREF=\"http:\/\/www.microsoft.com\/whdc\/devtools\/debugging\/debugstart.mspx\">\nthe symbol server<\/a> to get the symbols on-demand\nor, if you have a gigabyte of disk space, you can\n<a HREF=\"http:\/\/www.microsoft.com\/whdc\/devtools\/debugging\/symbolpkg.mspx\">\ndownload symbol packages<\/a> to get them all at one go.\nEven if you go for the symbol package, you still need the symbol server,\nsince it gets updated with symbols for binaries that have been updated\nsince the most recent service pack.)\n<\/p>\n<p>\nHere, we caught an exception in the <code>PeekMessageExceptionFilter<\/code>.\nWhat was the exception?\nWell, an exception filter receives a pointer to an\n<code>EXCEPTION_POINTERS<\/code> structure as its argument.\n<\/p>\n<pre>\ntypedef struct _EXCEPTION_POINTERS {\n    PEXCEPTION_RECORD ExceptionRecord;\n    PCONTEXT ContextRecord;\n} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;\n<\/pre>\n<p>\nHere, we see that the parameter to <code>PeekMessageExceptionFilter<\/code>\nis\n<\/p>\n<pre>\n030c21dc 76db6b0d <u>030c2204<\/u> 77b8d585 030c220c ole32!PeekMessageExceptionFilter+0x42\n0:0000&gt; dd 030c2204 l2\n030c2204 030c25d0 030c22e8\n         -------- --------\n         .exr     .cxr\n<\/pre>\n<p>\nThe first value points to the exception record and the second\npoints to the context record.\nYou can view the exception by typing <code>.exr 030c25d0<\/code>\nand view the context for the exception (i.e., what code was executing\nwhen the exception occurred) by typing <code>.cxr 030c22e8<\/code>.\nThose two values also appear as the first and (go figure) third\nparameters to <code>ExecuteHandler2<\/code>.\n<\/p>\n<p>\nIt so happens that doing the <code>.exr<\/code> on this particular\nexception record reports that the exception was <code>c015000f<\/code>\nwhich happens to be <code>STATUS_SXS_EARLY_DEACTIVATION<\/code>,\nand after setting the context to the exception context record,\nthe stack goes\n<\/p>\n<pre>\nChildEBP RetAddr\n030c262c 77d3c239 77d4a4b6 77d3e2c5 030c3767 ntdll!RtlDeactivateActivationContextUnsafeFast+0x233\n030c2630 77d4a4b6 77d3e2c5 030c3767 030c26a0 USER32!UserCallWinProcCheckWow+0x167\n030c2634 77d3e2c5 030c3767 030c26a0 77d4a46f USER32!_NLG_Return2\n030c265c 77d3e288 030c57b4 ffffffff 030c2688 USER32!__local_unwind2+0x70\n030c2688 77f36992 030c26f8 030c57b4 030c27a4 USER32!_except_handler3+0xd5\n030c26ac 77f36964 030c26f8 030c57b4 030c27a4 ntdll!ExecuteHandler2+0x26\n030c2a74 77b8d36d 030c6128 77b8d36d 00000000 ntdll!ExecuteHandler+0x24\n030c2a9c 77b8d59d 030c6128 030c2ac0 00000000 msvcrt!__global_unwind2+0x18\n030c2ac0 77f36992 030c2ba4 030c6128 030c2bc0 msvcrt!_except_handler3+0x75\n030c2ae4 77f36964 030c2ba4 030c6128 030c2bc0 ntdll!ExecuteHandler2+0x26\n030c2b8c 77f36796 030c1000 030c2bc0 030c2ba4 ntdll!ExecuteHandler+0x24\n030c2b8c 77b7aa54 030c1000 030c2bc0 030c2ba4 ntdll!KiUserExceptionDispatcher+0xe\n030c3300 77b7b4dc 030c3324 7715b1b4 00000000 msvcrt!_woutput_l+0x18\n<\/pre>\n<p>\nWow, we took an exception while trying to handle another exception!\n(It so happens this was easy to spot in the original stack trace,\nbut in the general case, the next outer exception may require digging.)\n<\/p>\n<p>\nRepeat the exercise with this next exception:\n<\/p>\n<pre>\n0:000&gt; .exr 030c2ba4\nExceptionAddress: 77b7aa54 (msvcrt!_woutput_l+0x00000018)\n   ExceptionCode: c00000fd (Stack overflow)\n  ExceptionFlags: 00000000\nNumberParameters: 2\n   Parameter[0]: 00000001\n   Parameter[1]: 030c2e88\n0:000&gt; .cxr 030c2bc0\neax=030c33b0 ebx=00000000 ecx=0000005c edx=00000000 esi=030c33c4 edi=030c33c4\neip=77b7aa54 esp=030c2e8c ebp=030c3300 iopl=0         nv up ei pl nz na pe nc\ncs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010202\nmsvcrt!_woutput_l+0x18:\n001b:77b7aa54 53          push    ebx\n<\/pre>\n<p>\nAha, so the SXS exception was triggered by a stack overflow.\nAt this new context, you can use the &#8220;k&#8221; command to see\nhow we got into this state.\n<\/p>\n<p>\nIt so happens that this particular bug was, as predicted,\na stack overflow caused by unintended recursion when a call\nto an off-thread COM object forced the calling thread to\nwait for the reply, during which time a new request came in.\nThe precise details of the problem aren&#8217;t important;\nthe goal today was to show how you can suck the exception\npointers out of the stack to see what Win32 exception was the\nsource of the problem.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Often, you find yourself staring at a stack trace for a caught exception and want to see the original exception. ChildEBP RetAddr Args to Child 030c21d0 76df3448 00000000 030c6138 76db6b0d ntdll!DbgBreakPoint 030c21dc 76db6b0d 030c2204 77b8d585 030c220c ole32!PeekMessageExceptionFilter+0x42 030c21e4 77b8d585 030c220c 00000000 030c220c ole32!CCliModalLoop::MyPeekMessage+0x41 030c220c 77f36992 030c25d0 030c6128 030c22e8 msvcrt!_except_handler3+0x61 030c2230 77f36964 030c25d0 030c6128 030c22e8 ntdll!ExecuteHandler2+0x26 [&hellip;]<\/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-30033","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Often, you find yourself staring at a stack trace for a caught exception and want to see the original exception. ChildEBP RetAddr Args to Child 030c21d0 76df3448 00000000 030c6138 76db6b0d ntdll!DbgBreakPoint 030c21dc 76db6b0d 030c2204 77b8d585 030c220c ole32!PeekMessageExceptionFilter+0x42 030c21e4 77b8d585 030c220c 00000000 030c220c ole32!CCliModalLoop::MyPeekMessage+0x41 030c220c 77f36992 030c25d0 030c6128 030c22e8 msvcrt!_except_handler3+0x61 030c2230 77f36964 030c25d0 030c6128 030c22e8 ntdll!ExecuteHandler2+0x26 [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/30033","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=30033"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/30033\/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=30033"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=30033"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=30033"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}