{"id":913,"date":"2014-05-23T07:00:00","date_gmt":"2014-05-23T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2014\/05\/23\/why-is-the-debugger-telling-me-i-crashed-because-my-dll-was-unloaded-when-i-see-it-loaded-right-here-happily-executing-code\/"},"modified":"2014-05-23T07:00:00","modified_gmt":"2014-05-23T07:00:00","slug":"why-is-the-debugger-telling-me-i-crashed-because-my-dll-was-unloaded-when-i-see-it-loaded-right-here-happily-executing-code","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20140523-00\/?p=913","title":{"rendered":"Why is the debugger telling me I crashed because my DLL was unloaded, when I see it loaded right here happily executing code?"},"content":{"rendered":"<p>\nA customer was puzzled by what appeared to be contradictory information\ncoming from the debugger.\n<\/p>\n<blockquote CLASS=\"q\">\n<p>\nWe have Windows Error Reporting failures that tell us that we\nare executing code in our DLL which has been unloaded.\nHere&#8217;s a sample stack:\n<\/p>\n<pre>\nChild-SP          RetAddr           Call Site\n00000037`7995e8b0 00007ffb`fe64b08e ntdll!RtlDispatchException+0x197\n00000037`7995ef80 000007f6`e5d5390c ntdll!KiUserExceptionDispatch+0x2e\n00000037`7995f5b8 00007ffb`fc977640 <font COLOR=\"blue\">&lt;Unloaded_contoso.dll&gt;+0x3390c<\/font>\n00000037`7995f5c0 00007ffb`fc978296 RPCRT4!NDRSRundownContextHandle+0x18\n00000037`7995f610 00007ffb`fc9780ed RPCRT4!DestroyContextHandlesForGuard+0xea\n00000037`7995f650 00007ffb`fc9b5ff4 RPCRT4!ASSOCIATION_HANDLE::~ASSOCIATION_HANDLE+0x39\n00000037`7995f680 00007ffb`fc9b5f7c RPCRT4!LRPC_SASSOCIATION::`scalar deleting destructor'+0x14\n00000037`7995f6b0 00007ffb`fc978b25 RPCRT4!LRPC_SCALL_BROKEN_FLOW::FreeObject+0x14\n00000037`7995f6e0 00007ffb`fc982e44 RPCRT4!LRPC_SASSOCIATION::MessageReceivedWithClosePending+0x6d\n00000037`7995f730 00007ffb`fc9825be RPCRT4!LRPC_ADDRESS::ProcessIO+0x794\n00000037`7995f870 00007ffb`fe5ead64 RPCRT4!LrpcIoComplete+0xae\n00000037`7995f910 00007ffb`fe5e928a ntdll!TppAlpcpExecuteCallback+0x204\n00000037`7995f980 00007ffb`fc350ce5 ntdll!TppWorkerThread+0x70a\n00000037`7995fd00 00007ffb`fe60f009 KERNEL32!BaseThreadInitThunk+0xd\n00000037`7995fd30 00000000`00000000 ntdll!RtlUserThreadStart+0x1d\n<\/pre>\n<p>\nBut if we ask the debugger what modules are loaded,\nour DLL is right there, loaded as happy as can be:\n<\/p>\n<pre>\n0:000&gt; lm\nstart             end                 module name\n...\n000007f6`e6000000 000007f6`e6050000   contoso    (deferred)\n...\n<\/pre>\n<p>\nIn fact, we can view other threads in the process,\nand they are happily running code in our DLL.\nWhat&#8217;s going on here?\n<\/p>\n<\/blockquote>\n<p>\nAll the information you need to solve this problem is given\nright there in the problem report.\nYou just have to put the pieces together.\n<\/p>\n<p>\nLet&#8217;s take a closer look at that\n<code>&lt;Unloaded_contoso.dll&gt;+0x3390c<\/code>\nentry.\nThe address that the symbol refers to is the return address\nfrom the previous frame:\n<code>000007f6`e5d5390c<\/code>.\nSubtract <code>0x3390c<\/code> from that, and you get\n<code>000007f6`e5d20000<\/code>,\nwhich is the base address of the unloaded module.\n<\/p>\n<p>\nOn the other hand, the <code>lm<\/code> command says that\nthe currently-loaded copy of <code>contoso.dll<\/code> is\nloaded at\n<code>000007f6`e6000000<\/code>.\nThis is a <i>different address<\/i>.\n<\/p>\n<p>\nWhat happened here is that <code>contoso.dll<\/code> was\nloaded into memory at <code>000007f6`e5d20000<\/code>,\nand then it ran for a while.\nThe DLL was then unloaded from memory,\nand later loaded back into memory.\nWhen it returned, it was loaded at a different address\n<code>000007f6`e6000000<\/code>.\nFor some reason\n(improper cleanup when unloading the first copy, most likely),\nthere was still a function pointer pointing into the old\nunloaded copy, and when <code>NDRS&shy;Rundown&shy;Context&shy;Handle<\/code>\ntries to call into that function pointer,\nit calls into an unloaded DLL,\nand you crash.\n<\/p>\n<p>\nWhen faced with something that seems impossible,\nyou need to look more closely for clues that suggest\nhow your implicit assumptions may be incorrect.\nIn this case, the assumption was that there was only one\ncopy of <code>contoso.dll<\/code>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A customer was puzzled by what appeared to be contradictory information coming from the debugger. We have Windows Error Reporting failures that tell us that we are executing code in our DLL which has been unloaded. Here&#8217;s a sample stack: Child-SP RetAddr Call Site 00000037`7995e8b0 00007ffb`fe64b08e ntdll!RtlDispatchException+0x197 00000037`7995ef80 000007f6`e5d5390c ntdll!KiUserExceptionDispatch+0x2e 00000037`7995f5b8 00007ffb`fc977640 &lt;Unloaded_contoso.dll&gt;+0x3390c 00000037`7995f5c0 00007ffb`fc978296 [&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-913","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>A customer was puzzled by what appeared to be contradictory information coming from the debugger. We have Windows Error Reporting failures that tell us that we are executing code in our DLL which has been unloaded. Here&#8217;s a sample stack: Child-SP RetAddr Call Site 00000037`7995e8b0 00007ffb`fe64b08e ntdll!RtlDispatchException+0x197 00000037`7995ef80 000007f6`e5d5390c ntdll!KiUserExceptionDispatch+0x2e 00000037`7995f5b8 00007ffb`fc977640 &lt;Unloaded_contoso.dll&gt;+0x3390c 00000037`7995f5c0 00007ffb`fc978296 [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/913","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=913"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/913\/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=913"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=913"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=913"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}