{"id":93526,"date":"2016-05-27T07:00:00","date_gmt":"2016-05-27T21:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/?p=93526"},"modified":"2019-03-13T11:03:37","modified_gmt":"2019-03-13T18:03:37","slug":"20160527-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20160527-00\/?p=93526","title":{"rendered":"Diagnosing a crash in unloaded_something.dll"},"content":{"rendered":"<p>A failure report came in to the shell team because Explorer crashed at shutdown in what the debugger reported as <code>unloaded_themeui.dll<\/code>. Time to dig in. <\/p>\n<pre>\nntdll!RtlpCallVectoredHandlers+0xeb\nntdll!RtlDispatchException+0x81\nntdll!KiUserExceptionDispatch+0x50\n&lt;Unloaded_themeui.dll&gt;+0x2bbfbd\n0x1fbdebe0\n0x1fbdebc0\n0x2357ef80\n\n&lt;Unloaded_themeui.dll&gt;+0x2bbfbd:\n00007ff8`e384bfbd ??              ???\n<\/pre>\n<p>Yup, there&#8217;s nothing loaded there all right. But let&#8217;s see what was loaded there before. <\/p>\n<pre>\n0:001&gt; lm\n...\nUnloaded modules:\n...\n00007ff8`e3590000 00007ff8`e385d000   themeui.dll\n00007ff8`e3840000 00007ff8`e385d000   abcdefg.dll\n<\/pre>\n<p>So there were two DLLs that used to be loaded at the address that crashed. Which could it be? <\/p>\n<pre>\n0:001&gt; !reload \/unl themeui.dll\n0:001&gt; u 00007ff8`e384bfbd\nthemeui!ext-ms-win-com-ole32-l1-1-1_NULL_THUNK_DATA_DLA &lt;PERF&gt; (themeui+0x2bffdd):\n00007ff8`e384bfbd 40              ???\n<\/pre>\n<p>Well, that doesn&#8217;t look like code. How about abcdefg? <\/p>\n<pre>\n0:001&gt; !reload \/unl abcdefg.dll\n0:001&gt; u 00007ff8`e384bfbd-80\n...\nabcdefg!AbcdefgImageList::GetClassImageList+0x1f\n00007ff8`e384bfb7 ff1593a20000    call    [abcdefg!_imp_SetupDiGetClassImageList]\n00007ff8`e384bfbd 85c0            test    eax,eax\n<\/pre>\n<p>That looks a lot more promising. What appears to have happened is that <code>abcdefg.dll<\/code> called <code>Setup&shy;Di&shy;Get&shy;Class&shy;Image&shy;List<\/code>, and while the call was in progress, the DLL got unloaded. When the call to <code>Setup&shy;Di&shy;Get&shy;Class&shy;Image&shy;List<\/code> finally returned, it returned to an unloaded DLL, which is the source of the crash. <\/p>\n<p><a HREF=\"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20130906-00\/?p=3303\">Reconstructing the stack<\/a> revealed a chain of calls that made sense in the context of <code>abcdefg.dll<\/code>, so this diagnosis is probably correct. (I&#8217;ve anonymized the name of the other DLL to protect the guilty.) <\/p>\n<p>What happened is that during Explorer startup, <code>abcdefg.dll<\/code> registered a wait with the thread pool on an event, and at shutdown it unregisters the wait. But it unregisters with <a HREF=\"https:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/ms686870(v=vs.85).aspx\">the <code>Unregister&shy;Wait<\/code> function<\/a>. If a callback is running at the time the wait is unregistered, the function returns <code>ERROR_IO_PENDING<\/code>, but nobody checks. The shutdown code proceeds to unload <code>abcdefg.dll<\/code>, and then we are left executing code that was freed. <\/p>\n<p>The code in <code>abcdefg.dll<\/code> needs to handle the case where the callback is still running at the time the wait is unregistered. You can use <a HREF=\"https:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/ms686876(v=vs.85).aspx\">the <code>Unregister&shy;Wait&shy;Ex<\/code> function<\/a>, which lets you pass an event that is set when the callback completes, or pass <code>INVALID_HANDLE_VALUE<\/code> to wait synchronously for the callback to complete before returning. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Find out what used to be loaded there.<\/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-93526","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Find out what used to be loaded there.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/93526","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=93526"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/93526\/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=93526"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=93526"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=93526"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}