<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Brandon's Blog</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/jiangyue/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/jiangyue/feed.xml</link>
    <description>Brandon Jiang&amp;#039;s technical blog about windows debugging</description>
    <lastBuildDate>Wed, 17 Apr 2019 03:41:30 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Graceful Completion of Thread Pool Wait Callback</title>
      <link>https://docs.microsoft.com/archive/blogs/jiangyue/graceful-completion-of-thread-pool-wait-callback</link>
      <pubDate>Mon, 06 Feb 2012 16:58:00 GMT</pubDate>
      <dc:creator><![CDATA[Brandon Jiang]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/jiangyue/2012/02/06/graceful-completion-of-thread-pool-wait-callback/</guid>
      <description><![CDATA[Windows thread pool API helps the developer to deal with the burdens of thread lifetime and...]]></description>
      <content:encoded><![CDATA[<p align="justify">Windows thread pool API helps the developer to deal with the burdens of thread lifetime and management, so that he/she only needs to focus on writing his/her work code as a callback function, and let it be automatically invoked by the thread pool thread. Books, such like <strong><a href="http://www.amazon.com/Concurrent-Programming-Windows-Joe-Duffy/dp/032143482X"><em>[CPW08]</em> </a></strong>chapter 7 and <a href="http://www.amazon.com/Windows-via-Pro-Jeffrey-Richter/dp/0735624240/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1328560667&amp;sr=1-1"><em>[WVCC07]</em> </a>chapter 11, and articles from MSDN magazine, such like <a href="http://msdn.microsoft.com/en-us/magazine/hh547107.aspx"><em>[MSDN07/10]</em> </a>and <a href="http://msdn.microsoft.com/en-us/magazine/hh547107.aspx"><em>[MSDN11/08]</em> </a>- <a href="http://msdn.microsoft.com/en-us/magazine/hh547107.aspx"><em>[MSDN11/11]</em></a> have details on various thread pool API.</p>
<p align="justify">&nbsp;</p>
<p><span style="font-size: medium;"><strong><em>Resource cleanup and Completion of Thread Pool Callbacks</em></strong></span></p>
<p>In order for the callback function to perform user defined tasks or works, it often has to use some custom resources, and those resources normally requires proper cleanup when the callback function is no longer needed, things like memories to be released, handles to be closed or DLL to be unloaded. Because of the concurrent nature of thread pool API, the resource cleanup and completion of thread pool callbacks must have some sort of synchronization, otherwise there would be a race condition between the thread which is cleaning up the resources and the callback threads which are still using those resources.</p>
<p>In particular, <strong>SetThreadpoolWait</strong> function allows a thread pool worker thread to call the wait object&rsquo;s callback function after the handle becomes signaled (or timeout happens). If the program wants to listen to the event notification continuously, it must re-register (by calling SetThreadpoolWait again) the event with the wait object before signaling it each time to trigger the wait callback . Usually, the re-register logic is put inside the callback function itself.</p>
<blockquote>
<p>VOID MyWaitCallback (&hellip;) <br />{ <br />&nbsp;&nbsp;&nbsp; //user codes to perform necessary tasks or works; <br /><strong>&nbsp;&nbsp;&nbsp; &hellip;;</strong></p>
&nbsp;&nbsp;&nbsp;&nbsp; //using some resources; <br /><strong>&nbsp;&nbsp;&nbsp; &hellip;;</strong>
<p>&nbsp;&nbsp;&nbsp; //re-register another wait <br /><span style="background-color: #ffff00;"><strong>&nbsp;&nbsp;&nbsp; SetThreadpoolWait(Wait, myWaitHandle, &hellip;);</strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #000000;" color="#000000"><strong>(1.1)</strong></span> <br /></span>};</p>
</blockquote>
<p>To overcome the race condition between any potential in-flight callbacks and the resource cleanup, the key is to make sure that the code waits for all callbacks to complete before starts freeing any resources. <strong><a href="http://www.amazon.com/Concurrent-Programming-Windows-Joe-Duffy/dp/032143482X"><em>[CPW08]</em> </a></strong>chapter 7 gives a three-step process to achieve this for wait callbacks: <em><strong>(1) cancel the waits, (2) wait for callbacks to finish, and finally (3) close the wait object</strong></em></p>
<blockquote>
<p>VOID StopTheWait (&hellip;) <br />{</p>
&nbsp;&nbsp;&nbsp;&nbsp; //Step 1: cancel the wait. <br /><span style="background-color: #00ff00;"><strong>&nbsp;&nbsp;&nbsp; SetThreadpoolWait(myWait, NULL, NULL);</strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>(1.2)</strong></span> <br />&nbsp;&nbsp;&nbsp; //Step 2: wait. m_pNduByteLimitWait(NULL), <br /><span style="background-color: #4bacc6;"><strong>&nbsp;&nbsp;&nbsp; WaitForThreadpoolWaitCallbacks(myWait, FALSE);</strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>(1.3)</strong></span> <br />&nbsp;&nbsp;&nbsp; //Step 3: close the wait object. <br /><span style="background-color: #9c85c0;"><strong>&nbsp;&nbsp;&nbsp; CloseThreadpoolWait(myWait);</strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>(1.4)</strong></span>
<p>&nbsp;&nbsp;&nbsp; //now it&rsquo;s safe to clean up resources, freeing the resource <br /><strong>&nbsp;&nbsp;&nbsp; &hellip;;</strong> <span style="background-color: #ffffff;"> <br /></span>};</p>
</blockquote>
<p>However, this solution is not completely correct and it does not solve all race conditions. Here it is why:</p>
<p>Imaging there is a in-flight callback, which is about to execute <strong><em><span style="background-color: #ffff00;">line (1.1)</span></em></strong>, and it gets preempted. At the same time, the program decides to stop the thread pool wait and start the cleaning up, so <em><span style="background-color: #00ff00;"><strong>line (1.2)</strong></span> </em>gets executed. After that the OS does context switch back to the callback thread, and executes <strong><em><span style="background-color: #ffff00;">line (1.1)</span></em></strong><em>. </em>The net effect of these interleaving operations is that <strong><em><span style="background-color: #ffff00;">line (1.1)</span></em></strong> happens after <em><span style="background-color: #00ff00;"><strong>line (1.2)</strong></span>, </em>and the wait is in fact not being canceled. Therefore, additional callbacks could be queued after <em><span style="background-color: #4bacc6;"><strong>line (1.3)</strong></span></em>, and start executing before <em><strong><span style="background-color: #9c85c0;">line (1.4)</span></strong></em>. In this case, the code moves on to free the resources concurrently as the callback executes.</p>
<p>&nbsp;</p>
<p><span style="font-size: medium;"><strong><em>Graceful completion of thread pool wait callback</em></strong></span></p>
<p>Here are two approaches for stopping thread pool wait in a truly graceful manner:</p>
<p><strong><span style="color: #004080;" color="#004080">If the program have control over the source of the wait notification</span></strong></p>
<p>In this case, the code can just simply turn off the source of the notification first, before waiting for any in-flight/queued callbacks to be finished. For example, it might call the matching <strong>UnregisterXXX</strong> function to stop the wait event from signaling, or stop calling <strong>SetEvent</strong> function if the signal is generated by the code itself. After than, it can call <strong>WaitForThreadpoolWaitCallbacks</strong> and <strong>CloseThreadpoolWait </strong>to stop thread pool wait safely.</p>
<p><strong><span style="color: #004080;" color="#004080">If the program does NOT have control over the source of the wait notification</span></strong></p>
<p>Neeraj Singh proposed the following pattern:</p>
<blockquote>
<p>VOID MyWaitCallback (&hellip;) <br />{ <br /><strong>&nbsp;&nbsp;&nbsp; &hellip;;</strong></p>
<p>&nbsp;&nbsp;&nbsp; if (<strong>dontReregister == FALSE</strong>) <br /><span style="background-color: #ffff00;"><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SetThreadpoolWait(Wait, myWaitHandle, &hellip;);</strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #000000;" color="#000000"><strong>(2.1)</strong></span> <br /></span>};</p>
<p>VOID StopTheWait (&hellip;) <br />{</p>
<p>&nbsp;&nbsp;&nbsp; //Step 1: set &ldquo;don&rsquo;t re-register&rdquo; flag. <br /><span style="background-color: #00ff00;"><strong>&nbsp;&nbsp;&nbsp; dontReregister = TRUE;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong><strong>(2.2)</strong></span> <br />&nbsp;&nbsp;&nbsp; //Step 2: wait for any in-flight callbacks which have NOT observed the flag to complete <br /><span style="background-color: #4bacc6;"><strong>&nbsp;&nbsp;&nbsp; WaitForThreadpoolWaitCallbacks(myWait, TRUE);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>(2.3)</strong></span> <br />&nbsp;&nbsp;&nbsp; //Step 3: call the wait. <br /><span style="background-color: #d19049;"><strong>&nbsp;&nbsp;&nbsp; SetThreadpoolWait(myWait, NULL, NULL);</strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>(2.4)</strong></span> <br />&nbsp;&nbsp;&nbsp; //Step 4: wait for any additional callbacks which should have observed the flag <br /><span style="background-color: #dd8484;"><strong>&nbsp;&nbsp;&nbsp; WaitForThreadpoolWaitCallbacks(myWait, TRUE);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>(2,5)</strong></span> <br />&nbsp;&nbsp;&nbsp; //Step 3: close the wait object. <br /><span style="background-color: #9c85c0;"><strong>&nbsp;&nbsp;&nbsp; CloseThreadpoolWait(myWait);</strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>(2.6)</strong></span></p>
<p>&nbsp;&nbsp;&nbsp; //now it&rsquo;s safe to clean up resources, freeing the resource <br /><strong>&nbsp;&nbsp;&nbsp; &hellip;;</strong> <span style="background-color: #ffff00;"> <br /></span>};</p>
</blockquote>
<p align="justify">The reason this pattern works is as following:</p>
<p align="justify">The if statement before <em><strong><span style="background-color: #ffff00;">line (2.1)</span></strong></em> makes sure that <strong>dontReregister</strong> flag is observed by any running callbacks before it calls <strong>SetThreadpoolWait</strong>. When the code decides to stop the thread pool wait, it first sets the <strong>dontReregister</strong> flag at <strong><em><span style="background-color: #00ff00;">line (2.2)</span></em></strong>. The first <strong>WaitForThreadpoolWaitCallbacks </strong>at <strong><em><span style="background-color: #4bacc6;">line (2.3)</span></em></strong> ensures that no callbacks are still running which have NOT observed that flag. After that, <strong><em><span style="background-color: #d19049;">line (2.4)</span></em></strong> prevents any further callbacks&nbsp;from being queued from this point onwards. The second <strong>WaitForThreadpoolWaitCallbacks</strong> at <strong><em><span style="background-color: #dd8484;">line (2.5)</span></em></strong> is added to wait for/cancel any in-flight/queued callbacks which may sneak in between <strong><em><span style="background-color: #4bacc6;">line (2.3</span></em></strong> and <strong><em><span style="background-color: #d19049;">line(2.4)</span></em></strong>. Finally, the wait object is closed at <em><strong><span style="background-color: #9c85c0;">line (2.6)</span></strong></em>.</p>
<p align="justify">Windows Thread Pool API already has necessary memory barriers inside, so the re-ordering of memory access has been constrained&nbsp;at <em><strong><span style="background-color: #ffff00;">line (2.1)</span></strong></em>&nbsp;and <strong><em><span style="background-color: #4bacc6;">line (2.3)</span></em></strong> even if nothing special is done for <strong>dontReregister </strong>flag.</p>
<p align="justify">&nbsp;</p>
<p><em><strong><span style="font-size: medium;">Take Away:</span></strong></em></p>
<p align="justify">On the surface, multithreading seems a straightforward and simple programming exercise and Windows Thread Pool API makes doing it even more accessible, but the truth is that it is extremely hard to get it done right. The bugs resulted from it are tricky and it&rsquo;s difficult for the programmers to locate the cause because of the timing involved, even with substantial test effect. Furthermore, the consequences of this kind of bugs are usually undefined (which often means devastating).</p>
<p align="justify">There are many other deeper aspects of multithreading, such like lock performance, memory/cache synchronization, power consumption and more, to be understood by the developers before they can really enjoy the benefit of multithreading. In short, there is a huge risk involved in adopting multithreading. Hence, before starting, carefully judge the cost/benefit and use it responsibly</p>
<p align="justify">&nbsp;</p>
<p><em><strong><span style="font-size: medium;">References:</span></strong></em></p>
<p>1. <strong><a href="http://www.amazon.com/Concurrent-Programming-Windows-Joe-Duffy/dp/032143482X">[CPW08] Concurrent Programming On Windows</a></strong></p>
<p>2. <a href="http://www.amazon.com/Windows-via-Pro-Jeffrey-Richter/dp/0735624240/ref=sr_1_1?s=books&amp;ie=UTF8&amp;qid=1328560667&amp;sr=1-1">[WVCC07] Windows via C/C++</a></p>
<p>3. <a href="http://msdn.microsoft.com/en-us/magazine/cc163327.aspx">[MSDN07/10] Improve Scalability With New Thread Pool APIs</a></p>
<p>4. <a href="http://msdn.microsoft.com/en-us/magazine/hh335066.aspx">[MSDN11/08] The Windows Thread Pool and Work</a></p>
<p>5. <a href="http://msdn.microsoft.com/en-us/magazine/hh394144.aspx">[MSDN11/09] The Thread Pool Environment</a></p>
<p>6. <a href="http://msdn.microsoft.com/en-us/magazine/hh456398.aspx">[MSDN11/10] Thread Pool Cancellation and Cleanup</a></p>
<p>7. <a href="http://msdn.microsoft.com/en-us/magazine/hh547107.aspx">[MSDN11/11] Thread Pool Synchronization</a></p>
<p>&nbsp;</p>
<p><strong><span style="font-size: small;">Thanks to <span style="color: #0080c0;">Neeraj Singh</span> and <span style="color: #0080c0;">Alex Bendetov</span> for answering my questions on this topic</span></strong></p>]]></content:encoded>
    </item>
    <item>
      <title>Case Study: Debug distributed application using packet analyzer</title>
      <link>https://docs.microsoft.com/archive/blogs/jiangyue/case-study-debug-distributed-application-using-packet-analyzer</link>
      <pubDate>Fri, 11 Feb 2011 01:40:00 GMT</pubDate>
      <dc:creator><![CDATA[Brandon Jiang]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/jiangyue/2011/02/11/case-study-debug-distributed-application-using-packet-analyzer/</guid>
      <description><![CDATA[Packet analyzers are powerful tools to troubleshoot remote communications between distributed...]]></description>
      <content:encoded><![CDATA[<p align="justify">Packet analyzers are powerful tools to troubleshoot remote communications between distributed applications. Microsoft are creating various new frameworks to lower the bar/cost for the developers to build distributed applications in Windows ecosystem, while those new technologies introduces additional layers and abstractions on top of existing APIs. And sometimes, if certain error happens in the lower stacks, the error information could be easily lost/translated by layers of wrapper codes in higher stacks, and this could make debugging such error extremely difficult. By using packet analyzers, one can see the raw information being transferred over the wire; therefore, this bottom-up approach could give developers a better understanding of what actually is going on first, and then, knowing what it is would make debugging in higher level more efficient later on.</p>
<p><span style="font-size: medium;"><strong><em>The Bug</em></strong>:</span></p>
<p>The following C# code segment is to obtain the hardware plug-and-play information from a remote machine:</p>
<blockquote>
<p style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;" class="MsoNormal"><span style="font-family: consolas;"><span><span style="color: #2b91af;"><span style="font-size: 9.5pt;">ConnectionOptions</span></span></span><span><span style="font-size: 9.5pt;"><span style="color: #000000;"> options = </span><span><span style="color: #0000ff;">new</span></span><span style="color: #000000;"> </span><span><span style="color: #2b91af;">ConnectionOptions</span></span><span style="color: #000000;">(</span></span></span></span></p>
<p style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;" class="MsoNormal"><span><span style="font-family: consolas;"><span style="mso-spacerun: yes;"><span style="color: #000000;"><span style="font-size: 9.5pt;">&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-size: 9.5pt;"><span><span style="color: #0000ff;">null</span></span><span style="color: #000000;">,</span></span></span></span></p>
<p style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;" class="MsoNormal"><span><span style="font-family: consolas;"><span style="mso-spacerun: yes;"><span style="color: #000000;"><span style="font-size: 9.5pt;">&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-size: 9.5pt;"><span><span style="color: #a31515;">"administrator"</span></span><span style="color: #000000;">,</span></span></span></span></p>
<p style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;" class="MsoNormal"><span><span style="font-family: consolas;"><span style="mso-spacerun: yes;"><span style="color: #000000;"><span style="font-size: 9.5pt;">&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-size: 9.5pt;"><span><span style="color: #a31515;">"!!123abc"</span></span><span style="color: #000000;">,</span></span></span></span></p>
<p style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;" class="MsoNormal"><span><span style="font-family: consolas;"><span style="mso-spacerun: yes;"><span style="color: #000000;"><span style="font-size: 9.5pt;">&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-size: 9.5pt;"><span><span style="color: #a31515;">"NTLMDOMAIN:10.177.17.6"</span></span><span style="color: #000000;">,</span></span></span></span></p>
<p style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;" class="MsoNormal"><span><span style="font-family: consolas;"><span style="mso-spacerun: yes;"><span style="color: #000000;"><span style="font-size: 9.5pt;">&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-size: 9.5pt;"><span><span style="color: #2b91af;">ImpersonationLevel</span></span><span style="color: #000000;">.Impersonate,</span></span></span></span></p>
<p style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;" class="MsoNormal"><span><span style="font-family: consolas;"><span style="mso-spacerun: yes;"><span style="color: #000000;"><span style="font-size: 9.5pt;">&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-size: 9.5pt;"><span><span style="color: #2b91af;">AuthenticationLevel</span></span><span style="color: #000000;">.PacketPrivacy,</span></span></span></span></p>
<p style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;" class="MsoNormal"><span><span style="font-family: consolas;"><span style="mso-spacerun: yes;"><span style="color: #000000;"><span style="font-size: 9.5pt;">&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-size: 9.5pt;"><span><span style="color: #0000ff;">true</span></span><span style="color: #000000;">,</span></span></span></span></p>
<p style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;" class="MsoNormal"><span><span style="font-family: consolas;"><span style="mso-spacerun: yes;"><span style="color: #000000;"><span style="font-size: 9.5pt;">&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-size: 9.5pt;"><span><span style="color: #0000ff;">null</span></span><span style="color: #000000;">,</span></span></span></span></p>
<p style="line-height: normal; text-indent: 21pt; margin: 0in 0in 0pt; mso-layout-grid-align: none;" class="MsoNormal"><span style="font-family: consolas;"><span><span style="color: #2b91af;"><span style="font-size: 9.5pt;">TimeSpan</span></span></span><span><span style="color: #000000; font-size: 9.5pt;">.MaxValue);</span></span></span></p>
<p style="line-height: normal; text-indent: 21pt; margin: 0in 0in 0pt; mso-layout-grid-align: none;" class="MsoNormal"><span><span style="font-family: consolas;"><span style="color: #000000; font-size: 9.5pt;">&nbsp;</span></span></span></p>
<p style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;" class="MsoNormal"><span style="font-family: consolas;"><span><span style="color: #2b91af;"><span style="font-size: 9.5pt;">ManagementScope</span></span></span><span><span style="font-size: 9.5pt;"><span style="color: #000000;"> scope = </span><span><span style="color: #0000ff;">new</span></span><span style="color: #000000;"> </span><span><span style="color: #2b91af;">ManagementScope</span></span><span style="color: #000000;">(</span></span></span></span></p>
<p style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;" class="MsoNormal"><span><span style="font-family: consolas;"><span style="mso-spacerun: yes;"><span style="color: #000000;"><span style="font-size: 9.5pt;">&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-size: 9.5pt;"><span><span style="color: #a31515;">@"\\10.177.17.6\root\cimv2"</span></span><span style="color: #000000;">, </span></span></span></span></p>
<p style="line-height: normal; text-indent: 21pt; margin: 0in 0in 0pt; mso-layout-grid-align: none;" class="MsoNormal"><span><span style="font-family: consolas;"><span style="color: #000000; font-size: 9.5pt;">options);</span></span></span></p>
<p style="line-height: normal; text-indent: 21pt; margin: 0in 0in 0pt; mso-layout-grid-align: none;" class="MsoNormal"><span><span style="font-family: consolas;"><span style="color: #000000; font-size: 9.5pt;">&nbsp;</span></span></span></p>
<p style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;" class="MsoNormal"><span><span style="font-family: consolas;"><span style="color: #000000; font-size: 9.5pt;">scope.Connect();</span></span></span></p>
<p style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;" class="MsoNormal"><span><span style="font-family: consolas;"><span style="color: #000000; font-size: 9.5pt;">&nbsp;</span></span></span></p>
<p style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;" class="MsoNormal"><span style="font-family: consolas;"><span><span style="color: #2b91af;"><span style="font-size: 9.5pt;">ManagementClass</span></span></span><span><span style="font-size: 9.5pt;"><span style="color: #000000;"> targetClass = </span><span><span style="color: #0000ff;">new</span></span><span style="color: #000000;"> </span><span><span style="color: #2b91af;">ManagementClass</span></span><span style="color: #000000;">(</span></span></span></span></p>
<p style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;" class="MsoNormal"><span><span style="font-family: consolas;"><span style="color: #000000;"><span style="mso-spacerun: yes;"><span style="font-size: 9.5pt;">&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 9.5pt;">scope,</span></span></span></span></p>
<p style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;" class="MsoNormal"><span><span style="font-family: consolas;"><span style="mso-spacerun: yes;"><span style="color: #000000;"><span style="font-size: 9.5pt;">&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-size: 9.5pt;"><span><span style="color: #0000ff;">new</span></span><span style="color: #000000;"> </span><span><span style="color: #2b91af;">ManagementPath</span></span><span style="color: #000000;">(</span><span><span style="color: #a31515;">"Win32_PnPEntity"</span></span><span style="color: #000000;">),</span></span></span></span></p>
<p style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;" class="MsoNormal"><span><span style="font-family: consolas;"><span style="mso-spacerun: yes;"><span style="color: #000000;"><span style="font-size: 9.5pt;">&nbsp;&nbsp;&nbsp; </span></span></span><span style="font-size: 9.5pt;"><span><span style="color: #0000ff;">null</span></span><span style="color: #000000;">);</span></span></span></span></p>
<p style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;" class="MsoNormal"><span><span style="font-family: consolas;"><span style="color: #2b91af; font-size: 9.5pt;">&nbsp;</span></span></span></p>
<p style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;" class="MsoNormal"><span style="font-family: consolas;"><span><span style="color: #2b91af;"><span style="font-size: 9.5pt;">ManagementObjectCollection</span></span></span><span><span style="color: #000000;"><span style="font-size: 9.5pt;"> collection = targetClass.GetInstances();</span><span style="mso-spacerun: yes;"><span style="font-size: 9.5pt;">&nbsp; </span></span></span></span></span></p>
<p style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;" class="MsoNormal"><span style="font-family: consolas;"><span><span style="color: #0000ff;"><span style="font-size: 9.5pt;">foreach</span></span></span><span><span style="font-size: 9.5pt;"><span style="color: #000000;"> (</span><span><span style="color: #2b91af;">ManagementBaseObject</span></span><span style="color: #000000;"> wmiObject </span><span><span style="color: #0000ff;">in</span></span><span style="color: #000000;"> collection)</span></span></span></span></p>
<p style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;" class="MsoNormal"><span><span style="font-family: consolas;"><span style="color: #000000; font-size: 9.5pt;">{</span></span></span></p>
<p style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;" class="MsoNormal"><span><span style="font-family: consolas; color: #000000;">&nbsp;&nbsp; ...</span></span></p>
<p style="line-height: normal; margin: 0in 0in 0pt; mso-layout-grid-align: none;" class="MsoNormal"><span><span style="font-family: consolas;"><span style="color: #000000; font-size: 9.5pt;">}</span></span></span></p>
</blockquote>
<p align="justify">The above codes use <strong><em><span style="color: #0080c0;"><a href="http://msdn.microsoft.com/en-us/library/ms257340(VS.80).aspx">WMI .NET</a></span></em></strong> with 3.5 SP1 runtime. It connect to the target machine (<span style="font-family: consolas;"><span style="color: #a31515; font-size: 9.5pt;">10.177.17.6</span></span>) using that machine&rsquo;s local administrator account, and it also specifies <strong><em><a href="http://msdn.microsoft.com/en-us/library/aa378749(VS.85).aspx">NTLM</a></em></strong> as the authentication protocol (<span style="font-family: consolas;"><span style="color: #a31515; font-size: 9.5pt;">NTLMDOMAIN</span></span>).&nbsp; After the connection is established, it remotely enumerates all the instances from WMI <span style="font-family: consolas;"><span style="color: #a31515; font-size: 9.5pt;">Win32_PnPEntity</span></span> class.</p>
<p align="justify">This seemingly simple code works fine in most of time; however, in one particular situation: if the target machine is running under <strong><a href="http://technet.microsoft.com/en-us/library/dd799308(WS.10).aspx"><em>Windows Preinstallation Environment 3.0</em></a></strong>, the code throws an COMException at some random time during the <span style="text-align: left; line-height: normal; font-family: consolas;"><span style="text-align: left;"><span style="text-align: left; color: #0000ff;"><span style="text-align: left;"><span style="font-size: 9.5pt;">foreach</span></span></span></span></span> loop. And the exception code can be either RPC_S_CALL_FAILED_DNE (0x800706BF The remote procedure call failed) or RPC_S_CALL_FAILED (0x800706BE The remote procedure call failed and did not execute).</p>
<p><em><strong><span style="font-size: medium;">The Debugging:</span></strong></em></p>
<p align="justify">Firstly, some knowledge about how Microsoft technologies are layered can help to understand why the exception talks about RPC failure and why it is the type of COMException:</p>
<p align="justify">The WMI .NET is just a wrapper above native <strong><em><a href="http://msdn.microsoft.com/en-us/library/aa394582(VS.85).aspx">WMI</a></em></strong> framework, and the remote communication feature of WMI is built on top of <strong><em><a href="http://msdn.microsoft.com/en-us/library/ms693719(VS.85).aspx">DCOM</a></em></strong>, and then again, DCOM utilize <strong><em><a href="http://msdn.microsoft.com/en-us/library/aa378651(VS.85).aspx">MSRPC</a></em></strong> as its inter-process communication infrastructure. So this exception is basically trying to tell the developers that, <strong>there is an error on the RPC level detected by DCOM stack, and then that error is reported to the .NET framework layer, and lastly .NET framework raises that error as COMException back to the user code</strong>.</p>
<p align="justify">If Windbg is attached to the codes, the output shows that error 0x80070721 and 0x80070005 always happened before that COMException</p>
<p><span style="font-family: courier new;"><strong>(dd8.a6c): Unknown exception - code 80070721 (first chance) <br />(dd8.a6c): Unknown exception - code 80070005 (first chance) <br />(dd8.a6c): Unknown exception - code 800706bf (first chance)</strong></span></p>
<p align="justify">0x8007005 is access denied, and 0x80070721 is less known, use !error command</p>
<p><span style="font-family: courier new;"><strong>0:000&gt; !error 0x80070721 <br />Error code: (HRESULT) 0x80070721 (2147944225) - A security package specific error occurred.</strong></span></p>
<p align="justify">It looks like some security related problem has happened right before the client codes failed. That&rsquo;s all the information there, and nothing furthermore can be investigated in the debugger (unless some serious reverse engineering are done, which is beyond this case study). It seems the debugging is getting into a dead-end, and now it is the time to start the bottom-up approach.</p>
<p align="justify"><span style="color: #004080;"><em>Note: Another possible approach is to setup the debugger to use symbols from <a href="http://referencesource.microsoft.com/serversetup.aspx">Microsoft Reference Source Server</a>, which would provide source codes access for .NET framework.</em></span></p>
<p align="justify">Use any packet analyzers (such as <strong><em><a href="http://www.wireshark.org/">WireShark</a></em></strong> or <strong><em><a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=983b941d-06cb-4658-b7f6-3088333d062f&amp;displaylang=en">Microsoft Network Monitor</a></em></strong>) and start a capture session, and repro this bug again, then save the capture file. The content of the capture file is shown below</p>
<p><span style="font-family: courier new;">No.&nbsp;&nbsp;&nbsp;&nbsp; Time&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Source&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Destination&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Protocol Info</span></p>
<p><span style="font-family: courier new;"><span style="background-color: #cccccc;">&nbsp;&nbsp;&nbsp; 406 5.078086&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DCERPC&nbsp;&nbsp; Bind: call_id: 3 ISystemActivator V0.0, <strong>NTLMSSP_NEGOTIATE</strong> <br />&nbsp;&nbsp;&nbsp; 407 5.078721&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DCERPC&nbsp;&nbsp; Bind_ack: call_id: 3, <strong>NTLMSSP_CHALLENGE</strong> accept max_xmit: 5840 max_recv: 5840 <br />&nbsp;&nbsp;&nbsp; 408 5.078987&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DCERPC&nbsp;&nbsp; AUTH3: call_id: 3, <strong>NTLMSSP_AUTH</strong>, User: <strong><span style="color: #333333;">10.177.17.6\administrator</span></strong></span></span></p>
<p align="justify">At the beginning of our capture file, the RPC layer established TCP connection and started to authenticate with the remote machine (10.177.17.6). The first 3 frames (highlighted in gray) are the standard 3-leg NTLM authentication protocol, NEGOTIATE &ndash;&gt; CHALLENGE &ndash;&gt; AUTH, see <strong><a href="http://www.amazon.com/Programming-Windows-Security-Keith-Brown/dp/0201604426"><em>[PWS00]</em></a></strong> chapter 7 for details. As recorded in frame 408 (AUTH), the credential used for authentication is the local administrator account on the target machine. Everything is as expected. <span style="font-family: courier new;"></span></p>
<p align="left"><span style="font-family: courier new;">&nbsp;&nbsp;&nbsp; 409 5.079045&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ISystemActivator RemoteCreateInstance request[Malformed Packet]&nbsp; <br />&nbsp;&nbsp;&nbsp; 411 5.081677&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ISystemActivator RemoteCreateInstance response[Malformed Packet]</span></p>
<p><span style="font-family: courier new;">&nbsp;&nbsp;&nbsp; ...</span></p>
<p><span style="font-family: courier new;">&nbsp;&nbsp;&nbsp; 517 5.334018&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DCERPC&nbsp;&nbsp; Request: call_id: 7 <strong>opnum: 6 ctx_id: 0 IEnumWbemClassObject</strong> V0 <br />&nbsp;&nbsp;&nbsp; 518 5.334248&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TCP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 49157 &gt; 59916 [ACK] Seq=221 Ack=789 Win=130560 Len=0 <br />&nbsp;&nbsp;&nbsp; 519 5.334574&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DCERPC&nbsp;&nbsp; Response: call_id: 7 ctx_id: 0 IEnumWbemClassObject V0</span></p>
<p><span style="font-family: courier new;">&nbsp;&nbsp;&nbsp; ...</span></p>
<p align="justify">After the initial authentication, the RPC conversation is established, and the DCOM starts to do its own stuff, such as remote activation (frame 409 - 411), reference count keeping, object lifecycle management etc., and then it is followed by WMI communication, such as IEnumWbemClassObject::Clone (frame 517 &ndash; 519, opnum 6 is Clone) and etc.. Most of those packages are about standard operations and have no interests to this bug, so they are not shown in this blog.</p>
<p align="justify"><span style="color: #004080;"><em>Note: see <a href="http://www.amazon.com/Essential-COM-Don-Box/dp/0201634465">[EC98]</a> and <a href="http://msdn.microsoft.com/en-us/library/cc250693(PROT.10).aspx">[MS-WMI]</a> for more information about DCOM and WMI</em></span></p>
<p align="justify">Then, what happened next is most interesting</p>
<p><span style="font-family: courier new;"><span style="background-color: #ffff00;">&nbsp;&nbsp;&nbsp; 520 5.334778&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DCERPC&nbsp;&nbsp; Alter_context: call_id: 8, 2 context items, 1st IRemUnknown2 V0.0, NTLMSSP_NEGOTIATE <br />&nbsp;&nbsp;&nbsp; 521 5.334891&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DCERPC&nbsp;&nbsp; Alter_context_resp: call_id: 8, NTLMSSP_CHALLENGE accept max_xmit: 5840 max_recv: 5840 <br />&nbsp;&nbsp;&nbsp; 522 5.335016&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DCERPC&nbsp;&nbsp; AUTH3: call_id: 8, NTLMSSP_AUTH, User: <span style="color: #ff0000;"><strong>REDMOND\jiangyue</strong></span> <br />&nbsp;&nbsp;&nbsp; 523 5.335047&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IRemUnknown2 RemQueryInterface request IID[1]=IManagedObject <br />&nbsp;&nbsp;&nbsp; 524 5.335231&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TCP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 49157 &gt; 59916 [ACK] Seq=821 Ack=1543 Win=129792 Len=0 <br />&nbsp;&nbsp;&nbsp; 525 5.335313&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DCERPC&nbsp;&nbsp; Fault: call_id: 8 ctx_id: 1 status: Unknown (<span style="color: #ff0000;"><strong>0x00000721</strong></span>) <br />&nbsp;&nbsp;&nbsp; 526 5.335379&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IRemUnknown2 RemQueryInterface request IID[1]=IProvideClassInfo <br />&nbsp;&nbsp;&nbsp; 527 5.335574&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DCERPC&nbsp;&nbsp; Fault: call_id: 9 ctx_id: 1 status: <strong><span style="color: #ff0000;">nca_s_fault_access_denied</span></strong></span> <br /><span style="color: #ff0000;"><strong>&nbsp;&nbsp;&nbsp; 528 5.335574&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TCP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 49157 &gt; 59916 [FIN, ACK] Seq=885 Ack=1687 Win=131328 Len=0 <br />&nbsp;&nbsp;&nbsp; 529 5.335600&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TCP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 59916 &gt; 49157 [ACK] Seq=1687 Ack=886 Win=130304 Len=0 <br />&nbsp;&nbsp;&nbsp; 530 5.336227&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TCP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 59916 &gt; 49157 [FIN, ACK] Seq=1687 Ack=886 Win=130304 Len=0 <br />&nbsp;&nbsp;&nbsp; 531 5.336356&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TCP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 49157 &gt; 59916 [ACK] Seq=886 Ack=1688 Win=131328 Len=0</strong></span> </span></p>
<p align="justify"><span style="font-family: verdana;"><span style="font-family: arial;">As highlighted by yellow color, RPC decided to re-authenticate with target machine using a different set of credential redmond\jiangyue (frame 520 - 522), and this credential is belong to the security token of current calling thread. However, redmond\jiangyue is not a valid credential on the target machine.&nbsp; Therefore, when the client machine called QueryInterface on the remote object for IManagedObject, the RPC layer on the remote machine responded with Fault message containing error code 0x00000721 (frame 525). Then again, the client tried to make another request for IProviderClassInfo to remote PRC layer, this time it responded with another Fault message containing error code 0x00000005 (access_denied). Those two errors matched the two exceptions seen by Windbg earlier on. After received two consecutive failed attempt, the RPC layer on the remote machine decided to send out the FIN message and close the current TCP connection, as indicated in frame 528 &ndash; 531.</span> </span></p>
<p><span style="font-family: courier new;"><span style="color: #008000;"><strong>&nbsp;&nbsp;&nbsp; 532 5.336862&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TCP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 59917 &gt; 49157 [SYN] Seq=0 Win=8192 Len=0 MSS=1460 WS=8 SACK_PERM=1 <br />&nbsp;&nbsp;&nbsp; 533 5.336943&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TCP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 49157 &gt; 59917 [SYN, ACK] Seq=0 Ack=1 Win=8192 Len=0 MSS=1460 WS=8 SACK_PERM=1 <br />&nbsp;&nbsp;&nbsp; 534 5.337055&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TCP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 59917 &gt; 49157 [ACK] Seq=1 Ack=1 Win=131328 Len=0</strong></span></span> <br /><span style="font-family: courier new;"><span style="background-color: #cccccc;">&nbsp;&nbsp;&nbsp; 535 5.337389&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DCERPC&nbsp;&nbsp; Bind: call_id: 11, 2 context items, 1st IEnumWbemClassObject V0.0, NTLMSSP_NEGOTIATE <br />&nbsp;&nbsp;&nbsp; 536 5.337595&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DCERPC&nbsp;&nbsp; Bind_ack: call_id: 11, NTLMSSP_CHALLENGE accept max_xmit: 5840 max_recv: 5840 <br />&nbsp;&nbsp;&nbsp; 537 5.337729&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DCERPC&nbsp;&nbsp; AUTH3: call_id: 11, NTLMSSP_AUTH, User: <strong>10.177.17.6\administrator</strong></span> <br />&nbsp;&nbsp;&nbsp; 538 5.337755&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DCERPC&nbsp;&nbsp; Request: call_id: 11 <span style="color: #333333;"><strong>opnum: 3 ctx_id: 0 IEnumWbemClassObject</strong></span> V0 <br />&nbsp;&nbsp;&nbsp; 539 5.337971&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TCP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 49157 &gt; 59917 [ACK] Seq=221 Ack=789 Win=130560 Len=0 <br />&nbsp;&nbsp;&nbsp; 540 5.338106&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DCERPC&nbsp;&nbsp; Response: call_id: 11 ctx_id: 0 IEnumWbemClassObject V0 <br />&nbsp;&nbsp;&nbsp; 541 5.338385&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DCERPC&nbsp;&nbsp; Alter_context: call_id: 12, 2 context items, 1st IRemUnknown2 V0.0 <br />&nbsp;&nbsp;&nbsp; 542 5.338450&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DCERPC&nbsp;&nbsp; Alter_context_resp: call_id: 12 Provider rejection, reason: Proposed transfer syntaxes not supported <br />&nbsp;&nbsp;&nbsp; 543 5.338491&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IRemUnknown2 RemQueryInterface request <br />&nbsp;&nbsp;&nbsp; 544 5.338605&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IRemUnknown2 RemQueryInterface response&nbsp; </span></p>
<p align="justify">The client seemed ignore all the security errors and continue its execution. The client made a new TCP connection to the remote machine by sending a new SYN message, as indicated in frame 532 &ndash; 534. And this time, it uses the right credential 10.177.17.6\administrator so it was enable to make some progress, until again the RPC layer decided to re-authenticate with a wrong credential redmond\jiangyue to query IManagedObject interface. This pattern repeated itself again and again in the captured file.</p>
<p align="justify"><span style="font-family: verdana;"><span style="font-family: arial;">The client was struggling to move forward until it reached the <span style="text-align: left; line-height: normal; font-family: consolas;"><span style="text-align: left;"><span style="text-align: left; color: #0000ff;"><span style="text-align: left;"><span style="font-size: 9.5pt;">foreach</span></span></span></span></span> loop, where it needed to call MoveNext() on the enumerator repeatedly.</span>&nbsp;&nbsp; </span></p>
<p><span style="font-family: courier new;"><span style="background-color: #ffff00;">&nbsp;&nbsp;&nbsp; 745 5.338889&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DCERPC&nbsp;&nbsp; Alter_context: call_id: 13 IWbemFetchSmartEnum V0.0, NTLMSSP_NEGOTIATE&nbsp; <br />&nbsp;&nbsp;&nbsp; 746 5.338996&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DCERPC&nbsp;&nbsp; Alter_context_resp: call_id: 13, NTLMSSP_CHALLENGE accept max_xmit: 5840 max_recv: 5840&nbsp; <br />&nbsp;&nbsp;&nbsp; 747 5.339116&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DCERPC&nbsp;&nbsp; AUTH3: call_id: 13, NTLMSSP_AUTH, User: <span style="color: #ff0000;"><strong>REDMOND\jiangyue</strong></span>&nbsp; <br />&nbsp;&nbsp;&nbsp; 748 5.339146&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DCERPC&nbsp;&nbsp; Request: call_id: 13 opnum: 3 ctx_id: 3 IWbemFetchSmartEnum V0&nbsp; <br />&nbsp;&nbsp;&nbsp; 749 5.339337&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TCP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 49157 &gt; 59917 [ACK] Seq=685 Ack=1759 Win=131328 Len=0&nbsp; <br />&nbsp;&nbsp;&nbsp; 750 5.339415&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DCERPC&nbsp;&nbsp; Fault: call_id: 13 ctx_id: 3 status: Unknown (<span style="color: #ff0000;"><strong>0x00000721</strong></span>)&nbsp; <br />&nbsp;&nbsp;&nbsp; 756 5.339866&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DCERPC&nbsp;&nbsp; Response: call_id: 14 ctx_id: 0 IEnumWbemClassObject V0&nbsp; <br />&nbsp;&nbsp;&nbsp; 757 5.339887&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TCP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 59917 &gt; 49157 [ACK] Seq=1871 Ack=5101 Win=131328 Len=0&nbsp; <br />&nbsp;&nbsp;&nbsp; 758 5.340308&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DCERPC&nbsp;&nbsp; Request: call_id: 15 opnum: 3 ctx_id: 3 IWbemFetchSmartEnum V0&nbsp; <br />&nbsp;&nbsp;&nbsp; 759 5.340479&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DCERPC&nbsp;&nbsp; Fault: call_id: 15 ctx_id: 3 status: <strong><span style="color: #ff0000;">nca_s_fault_access_denied</span></strong></span>&nbsp; <br /><strong><span style="color: #ff0000;">&nbsp;&nbsp;&nbsp; 760 5.340500&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TCP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 49157 &gt; 59917 [FIN, ACK] Seq=5133 Ack=1967 Win=131072 Len=0&nbsp; <br />&nbsp;&nbsp;&nbsp; 761 5.340515&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TCP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 59917 &gt; 49157 [ACK] Seq=1967 Ack=5134 Win=131328 Len=0&nbsp; <br />&nbsp;&nbsp;&nbsp; 762 5.340568&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TCP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 59917 &gt; 49157 [FIN, ACK] Seq=1967 Ack=5134 Win=131328 Len=0&nbsp; <br />&nbsp;&nbsp;&nbsp; 763 5.340651&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TCP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 49157 &gt; 59917 [ACK] Seq=5134 Ack=1968 Win=131072 Len=0</span></strong>&nbsp;&nbsp; </span></p>
<p>As highlighted above in yellow, after the client enter the <span style="line-height: normal; font-family: consolas;"><span><span style="color: #0000ff;"><span style="font-size: 9.5pt;">foreach</span></span></span></span> loop,&nbsp; it sent out the IWbemFetchSmartEnum::GetSmartEnum request (in frame 747, opnum 3) using the wrong credential once again, and it resulted the remote RPC to drop the TCP connection. This was the last user actions. After that, DCOM started garbage collections (frame 842-845) and then the communication over the wire was completely stopped.</p>
<p></p>
<p></p>
<p><span style="font-family: courier new;">&nbsp;&nbsp;&nbsp; 836 6.612612&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TCP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 59918 &gt; 49157 [SYN] Seq=0 Win=8192 Len=0 MSS=1460 WS=8 SACK_PERM=1&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; 837 6.612861&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TCP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 49157 &gt; 59918 [SYN, ACK] Seq=0 Ack=1 Win=8192 Len=0 MSS=1460 WS=8 SACK_PERM=1&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; 838 6.613020&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TCP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 59918 &gt; 49157 [ACK] Seq=1 Ack=1 Win=131328 Len=0</span>&nbsp; <br /><span style="font-family: courier new;">&nbsp;&nbsp;&nbsp; 839 6.613592&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DCERPC&nbsp;&nbsp; Bind: call_id: 17, 3 context items, 1st IRemUnknown2 V0.0, NTLMSSP_NEGOTIATE&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; 840 6.614019&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DCERPC&nbsp;&nbsp; Bind_ack: call_id: 17, NTLMSSP_CHALLENGE accept max_xmit: 5840 max_recv: 5840&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; 841 6.614199&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DCERPC&nbsp;&nbsp; AUTH3: call_id: 17, NTLMSSP_AUTH, User: 10.177.17.6\administrator&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; 842 6.614236&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IRemUnknown2 RemRelease request&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; 843 6.614429&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TCP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 49157 &gt; 59918 [ACK] Seq=245 Ack=881 Win=130560 Len=0&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; 844 6.614761&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IRemUnknown2 RemRelease response&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; 845 6.616079&nbsp;&nbsp;&nbsp; 10.177.17.15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.177.17.6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TCP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 59918 &gt; 49157 [RST, ACK] Seq=881 Ack=309 Win=0 Len=0</span></p>
<p>Frame 845 is the last record in the capture file.</p>
<p align="justify">After walking through the capture file, the root cause of the mysterious COMException should be clear now: Some code in WMI .NET layer was connect to remote RPC with a wrong credential, which makes the RPC server (on the remote machine) to drop the TCP connection. While the <span style="text-align: left; line-height: normal; font-family: consolas;"><span style="text-align: left;"><span style="text-align: left; color: #0000ff;"><span style="text-align: left;"><span style="font-size: 9.5pt;">foreach</span></span></span></span></span> loop was not aware of this, and kept reusing the dead TCP connection to make requests. When that happens, RPC reports generic error 0x6BE or 0x6BF</p>
<p align="justify">Now the next question is that why this issue only happens if the remote machine is running under WinPE environment, not in other full OS version. To answer that, another capture is made for the network traffic with the same codes running against a remote machine under full OS. By analyzing the new capture, it turns out that in full OS scenario, the RCP server behaves differently: It does NOT terminate the TCP connection when wrong credential is used.</p>
<p align="justify">With the knowledge obtained so far, do a search on Bing.com about &ldquo;WMI.NET IManagedobject Current Security Token&rdquo;, and it would reveal two KB articles from Microsoft (KB967622 and KB974893). They talked about exact the same issue faced here: When WMI.NET was using DCOM wrapper layer provided by .NET framework, the .NET framework is always trying to query IManagedObject interface for any COM object returned. However, .NET framework does not set the security blanket properly before issuing such a request. Without the security blanket being set, the request would use the default security context, i.e. the current security token of that process. This problem is annoying at least, because it would generate bunch of &ldquo;Failure Audit&rdquo; events on the remote machine, which causes security concerns, or in this WinPE case, it would actually disrupt the normal code execution.</p>
<p align="justify"><span style="color: #004080;"><em>Note: see <strong><a href="http://www.amazon.com/Programming-Windows-Security-Keith-Brown/dp/0201604426"><em>[PWS00]</em></a></strong> chapter 9 for more information about SetSecurityBlanket</em></span></p>
<p align="justify">The same KB articles provides hotfix from Microsoft to fix this bug for earlier version of .NET. From .NET 4.0 onwards, this fix has already been integrated. After installing the hotfix for .NET 3.5 SP1, the same codes run smoothly against a WinPE machine. By observing the network traffic using package analyzer, it can be confirmed that the remote QueryInterface for IManagedObject requests are not sent over the wire anymore.&nbsp;&nbsp;</p>
<p><em><strong><span style="font-size: medium;">Take Away:</span></strong></em></p>
<p align="justify">Coding in managed environment has greatly simplified the developer&rsquo;s life. While enjoying the mighty of modern programming techniques, it is also very helpful to understand the history of Microsoft technologies and the internal working of such technologies. To understand what happens under the hood, it is not only giving the developers the confidence when facing bugs, but also giving out examples how ones could design/implement to solve similar issues. Similarly, to know the path of how technologies evolve, it gives the developers the insight to those technologies&rsquo; rising and decline along with paradigm shift in this industry.</p>
<p align="justify">Package analyzers are efficient tools not only for traditional RPC based intranet applications, it is useful as well for newly Internet/Cloud based program. Having basic understanding of some popular network protocol, like TCP and HTTP, can greatly help to solve bugs. Therefore, It is well worthy to invest time to learn them. More inter-process communication debugging tips and expert advises can be found at <a href="http://www.amazon.com/Advanced-Windows-Debugging-Mario-Hewardt/dp/0321374460"><em>[AWD07]</em></a> Chapter 8.</p>
<p><em><strong><span style="font-size: medium;">References:</span></strong></em></p>
<p>1. <strong><a href="http://www.amazon.com/Programming-Windows-Security-Keith-Brown/dp/0201604426">[PWS00] Programming Windows Security</a></strong></p>
<p>2. <a href="http://www.amazon.com/Essential-COM-Don-Box/dp/0201634465">[EC98] Essential COM</a></p>
<p>3. <a href="http://msdn.microsoft.com/en-us/library/cc250693(PROT.10).aspx">[MS-WMI] Windows Management Instrumentation Remote Protocol Specification</a></p>
<p>4. <a href="http://www.amazon.com/Advanced-Windows-Debugging-Mario-Hewardt/dp/0321374460">[AWD07] Advanced Windows Debugging</a></p>
<p>&nbsp;</p>
<p><strong><span style="font-size: small;">Special thanks to <span style="color: #0080c0;">Gabriel</span> and <span style="color: #0080c0;">Pradeep</span>&rsquo;s help in solving this bug in the first place</span></strong></p>]]></content:encoded>
    </item>
    <item>
      <title>Build a free distributed project hosting using Mercurial and Windows Live Mesh</title>
      <link>https://docs.microsoft.com/archive/blogs/jiangyue/build-a-free-distributed-project-hosting-using-mercurial-and-windows-live-mesh</link>
      <pubDate>Tue, 26 Oct 2010 12:34:54 GMT</pubDate>
      <dc:creator><![CDATA[Brandon Jiang]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/jiangyue/2010/10/26/build-a-free-distributed-project-hosting-using-mercurial-and-windows-live-mesh/</guid>
      <description><![CDATA[For a small distributed project team, for example, a two-person’s team moonlighting for Windows...]]></description>
      <content:encoded><![CDATA[<br />  <p align="justify">For a small distributed project team, for example, a two-person’s team moonlighting for Windows Phone 7 applications/games, it is not necessarily a simply job to find a free or low-cost private/close source project hosting service: either they are too unreliable, or they come with too many limitations, and of course, the ads. Thus, besides getting a higher priced premiere hosting service, it seems the only alternative is to build a revision control system yourselves. This post introduces an easy way to setup such a versioning service, which can be used by every developers from the project team who doesn’t necessarily have direct connections together: The MercurialMesh (Mercurial + Windows Live Mesh). </p>  <p align="justify">Mercurial is a cross-platform, distributed revision control software released under GNU GPL <strong><a href="http://mercurial.selenic.com"><em>[MERC]</em></a></strong>. It is adopted as the core part of this versioning service because of Mercurial’s distributed architecture.&#160; For developers to share changes,&#160; Windows Live Mesh Service is used to synchronize different distributed repositories among each others. Windows Live Mesh Service is a free Internet-based file synchronization service <a href="http://explore.live.com/windows-live-mesh?os=other"><em>[WLM11]</em></a>, and it eliminates the needs of exposing an webserver on the Internet yourself for sharing changes, or manually sending changes to each others by emails. </p>  <p align="justify"><strong><em><font size="4">How to Setup</font></em></strong></p>  <p align="justify">1. Install Windows Live Mesh Service <a href="http://explore.live.com/windows-live-mesh?os=other"><em>[WLM11]</em> </a></p>  <p align="justify">2. Install Mercurial <strong><a href="http://mercurial.selenic.com"><em>[MERC]</em></a></strong></p>  <p align="justify"><strong>After both software have been stored, the only thing you need to do is to setup the master copy of your Mercurial repository and mark it as sync-able by Windows Live Mesh</strong></p>  <p align="justify">3. To create master copy of your Mercurial repository, use command “<em><strong><font color="#008000">hg init path_to_your_project_folder</font></strong></em>”. This command will initialize a new repository in that given path. If the given path doesn’t&#160; exist, it creates one.&#160; For example:</p>  <p><strong><font color="#008000">C:\Projects&gt;hg init myproject_master</font></strong> </p>  <p><font color="#004000">C:\Projects&gt;cd myproject_master      <br />C:\Projects\myproject_master&gt;dir       <br />Volume in drive C has no label.       <br />Volume Serial Number is 486B-D984 Directory of C:\Projects\myproject_master</font> </p>  <p><font color="#004000">26/10/2010&#160; 03:30 Ale&#160;&#160;&#160; &lt;DIR&gt;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; .      <br />26/10/2010&#160; 03:30 Ale&#160;&#160;&#160; &lt;DIR&gt;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ..       <br />26/10/2010&#160; 03:30 Ale&#160;&#160;&#160; &lt;DIR&gt;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; .hg       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 0 File(s)&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 0 bytes       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 3 Dir(s)&#160; 131,480,449,024 bytes free</font></p>  <p align="justify">4. Create a new Mercurial configuration file hgrc inside the .hg folder under your newly created repository. Open hgrc and specify a username you like for master repository by adding the following line:</p> <font color="#008000"><strong>[ui]      <br />username = maintainer &lt;maintainer@greatteam.com&gt;</strong></font>&#160;&#160; <br />  <p align="justify"><em><font color="#004080">Note: If you are using an existing folder with files inside, you can now add those files into the master repository by using command: “hg add” and then followed by “hg commit”. </font></em></p>  <p align="justify"><strong>Now the master repository is ready, and then the next step is to mark the master repository to be synchronized by Windows Live Mesh. <strong>After initial setup, the master repository must not be worked on directly, so this user account is used only for maintenance and recovery purposes. </strong></strong></p>  <p align="justify">5. Open Windows Live Mesh window, use “Sync a folder” option to add the folder where the master repository is to Windows Live Mesh. And then use “Shared with” option to give other developers the permissions to sync the same folder.</p>  <p align="justify"><strong>When you get here, the setup of your MercurialMesh versioing service is finished, You can start to use it</strong></p>  <p align="justify"><em><strong><font size="4">How to Use</font></strong></em></p>  <p align="justify">First, every developer should accept the sharing invitation sent by Windows Live Mesh, so that every one will have a master repository synced on his/her machine.</p>  <p align="justify"><font size="2"><strong>Create enlistment</strong>:</font> </p>  <p align="justify">This is to create a local working copy of the master repository. Use command: <em><strong><font color="#008000">“hg clone master_copy local_copy”</font></strong></em>, for example, </p>  <p><strong><font color="#008000">C:\Projects&gt;hg clone c:\Projects\myproject_master c:\Projects\myproject_local</font></strong>     <br /><font color="#004000">updating to branch default      <br />0 files updated, 0 files merged, 0 files removed, 0 files unresolved</font></p>  <p align="justify">Open hgrc inside the .hg folder of your newly created local repository, and specify a username for yourself adding the following line:</p> <font color="#008000"><strong>[ui]      <br />username = Alice &lt;alice@greatteam.com&gt;</strong></font>   <p align="justify"><em><font color="#004080">Note: Every developer must work on their own local repository, NOT on the master repository, otherwise, the revision history could be altered in an unwanted way </font></em></p>  <p align="justify"><font size="2"><strong>Getting the latest changes from others</strong>: </font></p>  <p align="justify">This is to update your local repository with the latest changes which have been submit to master repository by other developers&#160; </p>  <p align="justify">1. (Optional) Use “<em><strong><font color="#008000">hg incoming</font></strong></em>” to see what new changes are in the master repository, for example:</p>  <p><strong><font color="#008000">C:\Projects\myproject_local&gt;hg incoming ..\myproject_master       <br /></font></strong><font color="#004000">comparing with ..\myproject_master     <br />changeset:&#160;&#160; 0:40aa6d24fb24      <br />tag:&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; tip      <br />user:&#160;&#160;&#160;&#160;&#160;&#160;&#160; maintainer &lt;maintainer@greatteam.com&gt;      <br />date:&#160;&#160;&#160;&#160;&#160;&#160;&#160; Tue Oct 26 15:59:31 2010 -0700      <br />summary:&#160;&#160;&#160;&#160; Init master repro with helloworld</font></p>  <p align="justify">2. Once you confirm that you need to get those changes, use “<strong><em><font color="#008000">hg pull</font></em></strong>” to get those new changes, for example:</p>  <p><strong><font color="#008000">C:\Projects\myproject_local&gt;hg pull ..\myproject_master       <br /></font></strong><font color="#004000">pulling from ..\myproject_master     <br />requesting all changes      <br />adding changesets      <br />adding manifests      <br />adding file changes      <br />added 1 changesets with 1 changes to 1 files      <br />(run 'hg update' to get a working copy)</font></p>  <p align="justify">3. Don’t forget to apply those changes using “<strong><em><font color="#008000">hg update</font></em></strong>” to your local repository. for example:</p>  <p><strong><font color="#008000">C:\Projects\myproject_local&gt;hg update       <br /></font></strong><font color="#004000">1 files updated, 0 files merged, 0 files removed, 0 files unresolved</font></p>  <p align="justify"><em><font color="#004080">Note: “hg update” is the command actually modify your local files with those changes. Without “hg update” those new changes are just kept inside the Mercurial’s cache files, and they are not visible to you directly</font></em></p>  <p align="justify"><font size="2"><strong>Submit your changes to others</strong>:</font> </p>  <p align="justify">This is to submit your local changes into master repository, so other developer can received your changes later on if they uses “<em><strong><font color="#008000">hg pull</font></strong></em>”</p>  <p align="justify">1. (Optional) Use “<em><strong><font color="#008000">hg status</font></strong></em>” to confirm the list of files you intend to change, for example:</p>  <p><strong><font color="#008000">C:\Projects\myproject_local&gt;hg status       <br /></font></strong><font color="#004000">M helloworld.cpp</font></p>  <p align="justify">2. Submit the change to your local repository first by using “<strong><em><font color="#008000">hg commit</font></em></strong>”, for example,</p>  <p align="justify"><strong><font color="#008000">C:\Projects\myproject_local&gt;hg commit</font></strong></p>  <p align="justify">3. (Optional) See how is your change looks like to master repro by using “<strong><em><font color="#008000">hg outgoing</font></em></strong>” command, for example:</p>  <p><strong><font color="#008000">C:\Projects\myproject_local&gt;hg outgoing ..\myproject_master       <br /></font></strong><font color="#004000">comparing with ..\myproject_master     <br />searching for changes      <br />changeset:&#160;&#160; 1:0cd5548b8bbe      <br />tag:&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; tip      <br />user:&#160;&#160;&#160;&#160;&#160;&#160;&#160; Alice &lt;alice@greatteam.com&gt;      <br />date:&#160;&#160;&#160;&#160;&#160;&#160;&#160; Tue Oct 26 16:06:19 2010 -0700      <br />summary:&#160;&#160;&#160;&#160; Fix alignment</font></p>  <p align="justify">4. Make your local change into master repository by using “<strong><em><font color="#008000">hg push</font></em></strong>” command, for example:</p>  <p><font color="#008000"><strong>C:\Projects\myproject_local&gt;hg push ..\myproject_master       <br /></strong></font><font color="#004000">pushing to ..\myproject_master     <br />searching for changes      <br />adding changesets      <br />adding manifests      <br />adding file changes      <br />added 1 changesets with 1 changes to 1 files</font></p>  <p align="justify">Now your change is in the repository, and available to others who choose to “hg pull”</p>  <p align="justify"><font size="2"><strong>View the history</strong>:</font> </p>  <p align="justify">See the revision history of your project, use “<strong><em><font color="#008000">hg log</font></em></strong>” command, for example:</p>  <p><strong><font color="#008000">C:\Projects\myproject_local&gt;hg log       <br /></font></strong><font color="#004000">changeset:&#160;&#160; 1:0cd5548b8bbe     <br />tag:&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; tip      <br />user:&#160;&#160;&#160;&#160;&#160;&#160;&#160; Alice &lt;alice@greatteam.com&gt;      <br />date:&#160;&#160;&#160;&#160;&#160;&#160;&#160; Tue Oct 26 16:06:19 2010 -0700      <br />summary:&#160;&#160;&#160;&#160; Fix alignment</font></p>  <p><font color="#004000">changeset:&#160;&#160; 0:40aa6d24fb24     <br />user:&#160;&#160;&#160;&#160;&#160;&#160;&#160; maintainer &lt;maintainer@greatteam.com&gt;      <br />date:&#160;&#160;&#160;&#160;&#160;&#160;&#160; Tue Oct 26 15:59:31 2010 -0700      <br />summary:&#160;&#160;&#160;&#160; Init master repro with helloworld</font></p>  <p align="justify"><strong><font size="2">And more:</font></strong></p>  <p align="justify">There are more much things you can do using Mercurial as you expected from any other distributed revision control system, such like merging and conflict resolving etc. See more usage at Mercurial site <strong><a href="http://mercurial.selenic.com"><em>[MERC]</em></a></strong>. If you prefer GUI to command line window, TortoiseHg is good choice. And if you want even more integration with Visual Studio, then install VisualHg on top of TortoiseHg.</p>  <p align="justify">Also, you can enable Windows Live Mesh to sync your master repository with your Windows Live SkyDrive. That will keep a copy of your master repository in Microsoft’s cloud storage space. For that, you will give your repository the same availability as Microsoft Live SkyDrive promised&#160; </p>  <p align="justify"><strong><em><font size="4">Summary</font></em></strong></p>  <p align="justify">MercurialMesh (Mercurial + Windows Live Mesh) is very straightforward to setup. Basically, Mercurial is used for revision control, and Windows Live Mesh is used to share changes among developers. It is easy for daily use too: “hg pull” + “hg update” to receive changes from others; “hg commit” + “hg push” to submit your changes. This system costs your nothing, and it doesn’t requires any additional infrastructure setup, such like DNS Name, firewall and web server etc. For a small size team with infrequent changes exchange, it just simply works. </p>  <p align="justify">However, the scalability of this setup yet to be tested. There is a considerable delay between when a new change being made to master repository and when Windows Live Mesh finishes the sync.&#160; </p>  <p><em><strong><font size="4">References</font></strong></em></p>  <p>1. <strong><a href="http://mercurial.selenic.com">[MERC] Mercurial</a></strong></p>  <p>2. <a href="http://explore.live.com/windows-live-mesh?os=other">[WLM11] Windows Live Mesh 2011</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Case Study: Pack Mismatch</title>
      <link>https://docs.microsoft.com/archive/blogs/jiangyue/case-study-pack-mismatch</link>
      <pubDate>Tue, 11 May 2010 00:13:39 GMT</pubDate>
      <dc:creator><![CDATA[Brandon Jiang]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/jiangyue/2010/05/11/case-study-pack-mismatch/</guid>
      <description><![CDATA[Packing is a way to arrange data&#160; in memory using padding technique to align data at a memory...]]></description>
      <content:encoded><![CDATA[<p align="justify">Packing is a way to arrange data&#160; in memory using padding technique to align data at a memory offset equal to multiple of a fix size (usual the word size, but it could be byte size, DWORD size or any other size). The purpose of packing is to align the data memory layout to the microprocessor’s addressing model, and this can help increase performance (in some microprocessor architectures, misaligned data is even not allowed at all). Furthermore, packing can also be used to eliminate cache false sharing issue by forcing individual data structure to occupy an entire cache line. This is very important in high performance/parallel computing domain and it&#160; become more and more relevant&#160; to everybody else because the industrial trend of moving towards multi-core processors machine.</p>  <p align="justify"><em><font color="#004080">Note: See more information about pack and alignment in <strong><a href="http://msdn.microsoft.com/en-us/library/2e70t5y1.aspx">[MSDN-PACK]</a></strong>. </font></em><em><font color="#004080">For more on false sharing see <a href="http://www.amazon.com/Windows-via-Pro-Jeffrey-Richter/dp/0735624240">[WVC07]</a> Chapter 8.2 and <a href="http://www.amazon.com/Principles-Parallel-Programming-Calvin-Lin/dp/0321487907/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1273529408&amp;sr=1-1">[PPP09]</a> Chapter 1</font></em></p>  <p align="justify">In this case study, a heap bug is encountered due to incorrect use of the packing. The debugging technique demonstrated here includes some basic knowledge of Windows heap as described <a href="http://blogs.msdn.com/jiangyue/archive/2010/03/16/windows-heap-overrun-monitoring.aspx">in last post</a> and some understanding of data alignment in 64 bits Windows. </p>  <p align="justify"><font size="4"><strong><em>The Bug</em></strong>:</font></p>  <p align="justify"><em><strong>MyProgram</strong></em> is a 64-bit native application running under Windows 7, and it crashes consistently when it is launched. From the Event Viewer (Windows Logs/Application), the following error is logged:</p>  <p><font color="#ff0000"><font color="#800000" size="1">Faulting application name: MyProgram.exe, version: 0.0.0.0, time stamp: 0x4b9d52d7        <br />Faulting module name: ntdll.dll, version: 6.1.7600.16385, time stamp: 0x4a5be02b</font>       <br /><font color="#800000" size="1">Exception code:</font> <strong>0xc0000374</strong>       <br /></font><font color="#800000" size="1">Fault offset: 0x00000000000c6cd2      <br />Faulting process id: 0x1074       <br />Faulting application start time: 0x01cac3bc0628969b       <br />Faulting application path: d:\MyProgram\x64\Release\MyProgram.exe       <br />Faulting module path: C:\Windows\SYSTEM32\ntdll.dll       <br />Report Id: 4485473b-2faf-11df-8d9f-00151736c5a7</font></p>  <p align="justify">The exception code <strong><font color="#ff0000">0xc0000374</font></strong> means <strong>STATUS_HEAP_CORRUPTION</strong>. At this point, it is clear that this is a heap corruption bug, but it still requires some more debugging to find out the what actually corrupted the heap.</p>  <p align="justify"><em><strong><font size="4"></font></strong></em></p>  <p align="justify"><em><strong><font size="4">The Debugging:</font></strong></em> </p>  <p align="justify">As mentioned <a href="http://blogs.msdn.com/jiangyue/archive/2010/03/16/windows-heap-overrun-monitoring.aspx">in last post</a>, debugger could change the behavior of a heap related bug. Therefore, the <em><strong>–hd</strong></em> option is used during debugging so that the heap layout remains exactly the same as if the <em><strong>MyProgram.exe </strong></em>is running without debugger. In addition, the symbol path is set to Microsoft Public Symbol Server. </p>  <p align="justify"><em><font color="#004080">Note: <strong>–hd</strong> prevents the debugger to use the special heap which has a different layout than the default heap used by Windows.</font></em></p>  <p align="justify">The debugger outputs the following information when Windows Heap Manager detected the heap problem:</p>  <p><font color="#004000" face="Lucida Console">Critical error detected c0000374      <br />(1364.dd4): Break instruction exception - code 80000003 (first chance)       <br />ntdll!RtlUnhandledExceptionFilter+0x29f:       <br />00000000`77bc6c9f cc&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; int&#160;&#160;&#160;&#160; 3</font></p>  <p align="justify">With symbols loaded, uses command <strong>!heap</strong> to show more information, only the relevant outputs are shown </p>  <p><font color="#004000" face="Lucida Console">0:003&gt; !heap      <br /></font><font color="#004000" face="Lucida Console">Details: </font></p>  <p><font color="#004000" face="Lucida Console">Error address: <font color="#ff0000">00000000048b8410</font>       <br />Heap handle: 00000000048b0000       <br />Error type heap_failure_buffer_overrun (6)       <br />Last known valid blocks: before - 00000000048b8320, after - 00000000048b8fc0       <br />Stack trace:       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 0000000077bca4a8: ntdll!RtlpAnalyzeHeapFailure+0x00000000000003a8       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 0000000077b5ea71: ntdll!RtlpAllocateHeap+0x0000000000002176       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 0000000077b529ac: ntdll!RtlAllocateHeap+0x000000000000016c       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 0000000071a6c887: msvcr90!malloc+0x000000000000005b       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 0000000071a6c987: msvcr90!operator new+0x000000000000001f       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 000007fef2fdbf55: MyProvider!CGenericThreadPool::Initialize+0x0000000000000135       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 000007fef2fd74c5: MyProvider!SpecialThreadPool::SpecialThreadPool+0x0000000000000075       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 000007fef2fcb5cc: MyProvider!CPolicyProvider::CPolicyProvider+0x00000000000000ac       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 000007fef2fd3e84: MyProvider!MyProviderInitialize+0x0000000000000034       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 000007fef308e043: MyProgram!Initialize+0x00000000000002a3</font></p>  <p align="justify">As the output indicates, the heap issue is a buffer overrun, and the address where this happens is at <font color="#ff0000">00000000048b8410</font>. From the stack trace, it is obvious that overrun happens inside some constructor calls and Windows Heap Manager detected it when RtlAllocateHeap is called.</p>  <p align="justify">To get a close look at the error address and the heap block it belongs to:</p>  <p><font color="#004000" face="Lucida Console">0:003&gt; !heap -i 00000000048b8410      <br />Detailed information for block entry 00000000048b8410       <br />Assumed heap&#160;&#160;&#160;&#160;&#160;&#160; : 0x00000000048b0000 (Use !heap -i NewHeapHandle to change)       <br />Header content&#160;&#160;&#160;&#160; : 0x65010001 0x0000284A       <br />Owning segment&#160;&#160;&#160;&#160; : 0x00000000048b0000 (offset 0)       <br />Block flags&#160;&#160;&#160;&#160;&#160;&#160;&#160; : 0x0 (free )       <br />Total block size&#160;&#160; : 0x1 units (0x10 bytes)       <br />Previous block size: 0xf units (0xf0 bytes)       <br /><font color="#ff0000">Block CRC&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; : ERROR - current 65, expected 0</font>       <br />Free list entry&#160;&#160;&#160; : OK       <br />Previous block&#160;&#160;&#160;&#160; : <font color="#ff00ff">0x00000000048b8320</font>       <br />Next block&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; : 0x00000000048b8420</font></p>  <p align="justify">It reports checksum doesn’t match the expected value, which means this heap block’s header has been damaged. As explained in <a href="http://blogs.msdn.com/jiangyue/archive/2010/03/16/windows-heap-overrun-monitoring.aspx">in last post</a>, Windows Heap Manager cannot detect the overrun right at the moment when the damage happens, instead, it is only able to tell certain overrun has happened when the damaged block is used later on. In other word, if an operation <strong>X</strong> overrun its heap block <strong>a</strong>, which damages the next heap block <strong>a+1</strong>, Windows Heap Manager cannot detect <strong>X</strong>’s misconduct, However, if later on, the heap block <strong>a+1</strong> is used by other operation <strong>Y</strong>, then Windows Heap Manager will find out <strong>a+1</strong> has been damaged, but of course operation <strong>Y</strong> has nothing to do with this damage.</p>  <p align="justify">Therefore, what happened in this case is that, the heap block <font color="#ff0000">00000000048b8410 </font>is the <strong>a+1 </strong>block,&#160; the stack track shown above is the innocent operation <strong>Y</strong>.&#160; The real culprit is the one who operate on the previous heap block <font color="#ff00ff">0x00000000048b8320</font>. So, to get a better look at <font color="#ff00ff">0x00000000048b8320</font><font color="#000000">:</font></p>  <p><font color="#004000" face="Lucida Console">0:003&gt; !heap -i 0x00000000048b8320      <br />Detailed information for block entry 00000000048b8320       <br />Assumed heap&#160;&#160;&#160;&#160;&#160;&#160; : 0x00000000048b0000 (Use !heap -i NewHeapHandle to change)       <br />Header content&#160;&#160;&#160;&#160; : 0x7717D4D1 0x0B0028C5 (decoded : 0x0E01000F 0x0B000080)       <br />Owning segment&#160;&#160;&#160;&#160; : 0x00000000048b0000 (offset 0)       <br />Block flags&#160;&#160;&#160;&#160;&#160;&#160;&#160; : 0x1 (busy )       <br />Total block size&#160;&#160; : 0xf units (0xf0 bytes)       <br />Requested size&#160;&#160;&#160;&#160; : <font color="#ff0000">0xe5</font> bytes (unused 0xb bytes)       <br />Previous block size: 0x80 units (0x800 bytes)       <br />Block CRC&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; : OK - 0xe&#160; <br />Previous block&#160;&#160;&#160;&#160; : 0x00000000048b7b20       <br />Next block&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; : 0x00000000048b8410</font></p>  <p><font color="#004000" face="Lucida Console">0:003&gt; !heap -x 0x00000000048b8320      <br />HEAP 00000000048b0000 (Seg 00000000048b0000) At 00000000048b8410 Error: invalid block size </font></p>  <p><font color="#004000" face="Lucida Console">Entry&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; User&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Heap&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Segment&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Size&#160; PrevSize&#160; Unused&#160;&#160;&#160; Flags      <br />-------------------------------------------------------------------------------------------------------------       <br />00000000048b8320&#160; <font color="#0080ff">00000000048b8330</font>&#160; 00000000048b0000&#160; 00000000048b0000&#160;&#160;&#160;&#160;&#160;&#160;&#160; f0&#160;&#160;&#160;&#160;&#160;&#160; 800&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; b&#160; busy</font> </p>  <p align="justify">It tells this block was assigned to an allocation request for size of <font color="#ff0000">0xe5</font> bytes memory. And look back at the stack track from the first <strong>!heap</strong> command, there are quite a few constructors calls. It is reasonable to guess that this heap block was allocated for an object. To show the content of this heap block, just do <strong>d </strong>command at the user portion of this heap block at address <font color="#0080ff">00000000048b8330</font>, i.e. heap block header address + header size(0x10):</p>  <p><font color="#004000" face="Lucida Console">0:003&gt; dq 00000000048b8330&#160; <br />00000000`048b8330&#160; <font color="#ff0000">000007fe`f2fc1848</font> 00000000`0478ded0       <br />00000000`048b8340&#160; 00000000`00000000 00000000`00000000       <br />00000000`048b8350&#160; 00000000`00000000 00000000`00000000       <br />00000000`048b8360&#160; 00000000`00000000 00000000`00000000       <br />00000000`048b8370&#160; 00000000`00000000 00000000`00000000       <br />00000000`048b8380&#160; 00000000`00000000 00000000`00000000       <br />00000000`048b8390&#160; 00000000`00000000 00000000`00000000       <br />00000000`048b83a0&#160; 000007fe`f2fc1880 0000000c`00000000</font></p>  <p align="justify">If the assumption(this block is allocated for an object) is right, then the first 8 bytes should be pointing to the virtual function table of that object. To verify this, do <strong>ln</strong> command at the address pointed by the first 8 bytes </p>  <p><font color="#004000" face="Lucida Console">0:003&gt; ln <font color="#ff0000">000007fe`f2fc1848</font>       <br />(000007fe`f2fc1848)&#160;&#160; MyProvider!<strong>CPolicyProvider</strong>::`vftable' Exact matches:</font></p>  <p align="justify">It is indeed an object, and this object is an instance of type <strong>CPolicyProvider</strong>. It is clear now that the heap block <font color="#ff00ff">0x00000000048b8320</font> was allocated as a response to&#160; the constructor call of class <strong>CPolicyProvider</strong>.</p>  <p align="justify"><em><font color="#004080">Note: For more information about C++ Language Memory Model, see <strong><a href="http://www.amazon.com/Inside-Object-Model-Stanley-Lippman/dp/0201834545">[ICOM96]</a></strong></font></em></p>  <p align="justify"><em><font color="#004080">Note: Another easy way to find out what functions has operated on certain heap block is to use the stack trace. By specifying <strong>+ust</strong> flag with <strong>gflags.exe</strong> tool, it enables the user mode stack trace. After it is enabled, <strong>!heap –i</strong> command will automatically includes stack trace whenever available. This is a very useful feature.</font></em></p>  <p align="justify">To know the size of this type, do </p>  <p><font color="#004000" face="Lucida Console">0:003&gt; ?? sizeof (OSDPxeProvider!OSD::CPolicyProvider)      <br />unsigned int64 0xe5</font></p>  <p align="justify">It returns 0xe5 bytes, and it seems consistent with the size from heap block information. However, when trying to display the detailed type information using <strong>dt</strong> command, some inconsistency has been noticed (only relevant output has been shown below) :</p>  <p><font color="#004000" face="Lucida Console">0:003&gt; dt -r MyProvider!CPolicyProvider      <br />&#160;&#160; +0x000 __VFN_table : Ptr64       <br />&#160;&#160; =000007fe`f2fec5d0 CPolicyProvider::s_theInstance : Ptr64 CPolicyProvider       <br />&#160;&#160;&#160;&#160;&#160; +0x000 __VFN_table : Ptr64       <br />&#160;&#160;&#160;&#160;&#160; =000007fe`f2fec5d0 CPolicyProvider::s_theInstance : Ptr64 CPolicyProvider       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +0x000 __VFN_table : Ptr64       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; =000007fe`f2fec5d0 CPolicyProvider::s_theInstance : Ptr64 CPolicyProvider       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +0x008 m_hProvider&#160;&#160;&#160;&#160;&#160; : Ptr64 Void       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +0x010 configPtr&#160;&#160;&#160;&#160;&#160;&#160;&#160; : shared_any&lt;Config *,close_delete,null_t,enum Unique&gt;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +0x020 m_bootCounter&#160;&#160;&#160; : shared_ptr&lt;IPerformanceCounter&gt;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +0x030 m_abortCounter&#160;&#160; : shared_ptr&lt;IPerformanceCounter&gt;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +0x040 m_passCounter&#160;&#160;&#160; : shared_ptr&lt;IPerformanceCounter&gt;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +0x050 m_requestTotalCounter : shared_ptr&lt;IPerformanceCounter&gt;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +0x060 m_requestTimedOutCounter : shared_ptr&lt;IPerformanceCounter&gt;       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; +0x070 m_threadPool&#160;&#160;&#160;&#160; : SpecialThreadPool       <br />&#160;&#160;&#160;&#160;&#160; +0x008 m_hProvider&#160;&#160;&#160;&#160;&#160; : Ptr64 Void</font></p> <strong><font color="#0080ff">&#160;&#160;&#160;&#160;&#160; . . . Other fields are not shown here</font></strong>   <br />  <p><font color="#004000" face="Lucida Console">&#160;&#160; <font color="#ff0000"><strong>+0x070</strong></font> m_threadPool&#160;&#160;&#160;&#160; : SpecialThreadPool       <br />&#160;&#160;&#160;&#160;&#160; +0x000 __VFN_table : Ptr64       <br />&#160;&#160;&#160;&#160;&#160; +0x008 m_bIsInitialized : Bool       <br />&#160;&#160;&#160;&#160;&#160; +0x009 m_bInitializeCOM : Bool       <br />&#160;&#160;&#160;&#160;&#160; +0x00c m_dwCurrentNumberOfThreads : Uint4B</font><font color="#004000"></font> </p>  <p><font color="#0080ff"><strong><font face="Lucida Console">&#160;&#160;&#160;&#160; <font face="ve">&#160;</font><font face="Verdana">... Other fields are not shown here</font></font></strong></font></p>  <p><font color="#004000" face="Lucida Console">&#160;&#160;&#160;&#160;&#160; +0x078 m_bIsCsThreadListInitialized : Bool      <br />&#160;&#160;&#160;&#160;&#160; +0x079 m_bIsShuttingDown : Bool       <br />&#160;&#160;&#160;&#160;&#160; <strong><font color="#ff0000">+0x07a</font></strong> m_bAutoCreateNewThreads : Bool       <br />&#160;&#160;&#160;&#160;&#160; =000007fe`f2fc0000 THREAD_COUNT&#160;&#160;&#160;&#160; : Uint4B</font></p>  <p></p>  <p align="justify">The last field of <strong>CPolicyProvider </strong>is type of <strong>SpecialThreadPool</strong>, size of <strong>SpecialThreadPool</strong> is at least <font color="#ff0000">0x7a </font>bytes(depends on padding). So, the entire size of <strong>CPolicyProvider </strong>should be at least <font color="#ff0000">0x70 + 0x7a = 0xea</font>. In other words, the instance memory layout has more bytes than the actual memory allocated (0xea &gt; 0xe5). This definitely causes heap buffer overrun if there is a write operation to the last field of <strong>CPolicyProvider</strong>.</p>  <p align="justify">Looking into the source code, type <strong>SpecialThreadPool </strong>is inherited from type <strong>CGenericThreadPool</strong>, and it just has some more additional static field and functions than the parent class. Hence, the memory layout of <strong>SpecialThreadPool </strong>should be exact the same as <strong>CGenericThreadPool</strong>. However, the size of <strong>CGenericThreadPool</strong> reported by debugger is different from the size of <strong>SpecialThreadPool </strong>reported :</p> <font color="#004000" face="Lucida Console">0:003&gt; ?? sizeof (CGenericThreadPool)    <br />unsigned int64 0x80     <br /></font>  <p><font color="#004000" face="Lucida Console">0:003&gt; ?? sizeof (SpecialThreadPool)      <br />unsigned int64 0x75</font></p>  <p>To understand where has gone wrong, the memory layout of <strong>SpecialThreadPool </strong>needs to be examined more closely:</p>  <p><font color="#004000" face="Lucida Console">0:003&gt; dt OSD::PXERequestThreadPool      <br />OSDPxeProvider!OSD::PXERequestThreadPool       <br />&#160;&#160; +0x000 __VFN_table : Ptr64       <br />&#160;&#160; +0x008 m_bIsInitialized : Bool       <br />&#160;&#160; +0x009 m_bInitializeCOM : Bool       <br />&#160;&#160; +0x00c m_dwCurrentNumberOfThreads : Uint4B       <br />&#160;&#160; +0x010 m_dwMaximumNumberOfThreads : Uint4B       <br />&#160;&#160; +0x018 m_hCompletionPort : Ptr64 Void       <br />&#160;&#160; +0x020 m_hMonitoringThread : Ptr64 Void       <br />&#160;&#160; +0x028 m_lastActivationTime : Int8B       <br />&#160;&#160; +0x030 m_lNumberOfThreadsWaiting : Int4B       <br />&#160;&#160; +0x034 m_dwCompletionThreadTimeout : Uint4B       <br />&#160;&#160; +0x038 m_spThreadContextArray : Ptr64 CThreadContext       <br />&#160;&#160; +0x040 m_listActivationTime : _LIST_ENTRY       <br />&#160;&#160; +0x050 m_csThreadList&#160;&#160; : _RTL_CRITICAL_SECTION       <br />&#160;&#160; +0x078 m_bIsCsThreadListInitialized : Bool       <br />&#160;&#160; +0x079 m_bIsShuttingDown : Bool       <br />&#160;&#160; +0x07a m_</font><font color="#004000" face="Lucida Console">bAutoCreateNewThreads : Bool</font></p>  <p>where the layout of <font color="#004000"><strong>_LIST_ENTRY</strong></font> and <font color="#004000"><strong>_RTL_CRITICAL_SECTION</strong></font> are:</p> <font color="#004000" face="Lucida Console">0:003&gt; dt _LIST_ENTRY    <br />msvcr90!_LIST_ENTRY     <br />&#160;&#160; +0x000 Flink&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; : Ptr64 _LIST_ENTRY     <br />&#160;&#160; +0x008 Blink&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; : Ptr64 _LIST_ENTRY     <br />0:003&gt; dt _RTL_CRITICAL_SECTION     <br />msvcr90!_RTL_CRITICAL_SECTION     <br />&#160;&#160; +0x000 DebugInfo&#160;&#160;&#160;&#160;&#160;&#160;&#160; : Ptr64 _RTL_CRITICAL_SECTION_DEBUG     <br />&#160;&#160; +0x008 LockCount&#160;&#160;&#160;&#160;&#160;&#160;&#160; : Int4B     <br />&#160;&#160; +0x00c RecursionCount&#160;&#160; : Int4B     <br />&#160;&#160; +0x010 OwningThread&#160;&#160;&#160;&#160; : Ptr64 Void     <br />&#160;&#160; +0x018 LockSemaphore&#160;&#160;&#160; : Ptr64 Void     <br />&#160;&#160; +0x020 SpinCount&#160;&#160;&#160;&#160;&#160;&#160;&#160; : Uint8B</font>   <p>And more intuitively, the memory layout of <strong>SpecialThreadPool </strong>could be represented as following block diagram (the unit in the brackets is byte):</p>  <table border="1" cellspacing="0" cellpadding="2" width="536"><tbody>     <tr>       <td valign="top" width="10"><font color="#0000ff">0x00</font></td>        <td valign="top" width="526"><font color="#0000ff">Ptr64 (8)</font></td>     </tr>   </tbody></table>  <table border="1" cellspacing="0" cellpadding="2" width="536"><tbody>     <tr>       <td valign="top" width="10"><font color="#0000ff">0x08</font></td>        <td valign="top" width="60"><font color="#0000ff">bool (1)</font></td>        <td valign="top" width="58"><font color="#0000ff">bool (1)</font></td>        <td valign="top" width="285"><font color="#0000ff">Uint4B(4)</font></td>        <td valign="top" width="121"><strong><font color="#ff0000">padding(2)</font></strong></td>     </tr>   </tbody></table>  <table border="1" cellspacing="0" cellpadding="2" width="536"><tbody>     <tr>       <td valign="top" width="10"><font color="#0000ff">0x10</font></td>        <td valign="top" width="262"><font color="#0000ff">Uint4B (4)</font></td>        <td valign="top" width="264"><strong><font color="#ff0000">padding(4)</font></strong></td>     </tr>   </tbody></table>  <table border="1" cellspacing="0" cellpadding="2" width="536"><tbody>     <tr>       <td valign="top" width="10"><font color="#0000ff">0x18</font></td>        <td valign="top" width="528"><font color="#0000ff">Ptr64 (8)</font></td>     </tr>   </tbody></table>  <table border="1" cellspacing="0" cellpadding="2" width="536"><tbody>     <tr>       <td valign="top" width="10"><font color="#0000ff">0x20</font></td>        <td valign="top" width="528"><font color="#0000ff">Ptr64 (8)</font></td>     </tr>   </tbody></table>  <table border="1" cellspacing="0" cellpadding="2" width="536"><tbody>     <tr>       <td valign="top" width="10"><font color="#0000ff">0x28</font></td>        <td valign="top" width="529"><font color="#0000ff">Int8B (8)</font></td>     </tr>   </tbody></table>  <table border="1" cellspacing="0" cellpadding="2" width="536"><tbody>     <tr>       <td valign="top" width="10"><font color="#0000ff">0x30</font></td>        <td valign="top" width="261"><font color="#0000ff">Int4B (4)</font></td>        <td valign="top" width="264"><font color="#0000ff">Uint4B(4)</font></td>     </tr>   </tbody></table>  <table border="1" cellspacing="0" cellpadding="2" width="536"><tbody>     <tr>       <td valign="top" width="10"><font color="#0000ff">0x38</font></td>        <td valign="top" width="527"><font color="#0000ff">Ptr64 (8)</font></td>     </tr>   </tbody></table>  <table border="1" cellspacing="0" cellpadding="2" width="536"><tbody>     <tr>       <td valign="top" width="10"><font color="#0000ff">0x40</font></td>        <td valign="top" width="536"><font color="#0000ff">_LIST_ENTRY.Ptr64 (8)&#160; </font></td>     </tr>   </tbody></table>  <table border="1" cellspacing="0" cellpadding="2" width="536"><tbody>     <tr>       <td valign="top" width="10"><font color="#0000ff">0x48</font></td>        <td valign="top" width="529"><font color="#0000ff">_LIST_ENTRY.Ptr64 (8)</font></td>     </tr>   </tbody></table>  <table border="1" cellspacing="0" cellpadding="2" width="536"><tbody>     <tr>       <td valign="top" width="10"><font color="#0000ff">0x50</font></td>        <td valign="top" width="527"><font color="#0000ff">_RTL_CRITICAL_SECTION.Ptr64 (8)</font></td>     </tr>   </tbody></table>  <table border="1" cellspacing="0" cellpadding="2" width="536"><tbody>     <tr>       <td valign="top" width="10"><font color="#0000ff">0x58</font></td>        <td valign="top" width="265"><font color="#0000ff">_RTL_CRITICAL_SECTION.Int4B (4)</font></td>        <td valign="top" width="270"><font color="#0000ff">_RTL_CRITICAL_SECTION.Int4B (4)</font></td>     </tr>   </tbody></table>  <table border="1" cellspacing="0" cellpadding="2" width="536"><tbody>     <tr>       <td valign="top" width="10"><font color="#0000ff">0x60</font></td>        <td valign="top" width="542"><font color="#0000ff">_RTL_CRITICAL_SECTION.Ptr64 (8)</font></td>     </tr>   </tbody></table>  <table border="1" cellspacing="0" cellpadding="2" width="536"><tbody>     <tr>       <td valign="top" width="10"><font color="#0000ff">0x68</font></td>        <td valign="top" width="537"><font color="#0000ff">_RTL_CRITICAL_SECTION.Ptr64 (8)</font></td>     </tr>   </tbody></table>  <table border="1" cellspacing="0" cellpadding="2" width="536"><tbody>     <tr>       <td valign="top" width="10"><font color="#0000ff">0x70</font></td>        <td valign="top" width="531"><font color="#0000ff">_RTL_CRITICAL_SECTION.Uint8B (8)</font></td>     </tr>   </tbody></table>  <table border="1" cellspacing="0" cellpadding="2" width="536"><tbody>     <tr>       <td valign="top" width="10"><font color="#0000ff">0x78</font></td>        <td valign="top" width="59"><font color="#0000ff">bool (1) </font></td>        <td valign="top" width="53"><font color="#0000ff">bool(1)</font></td>        <td valign="top" width="50"><font color="#0000ff">bool(1)</font></td>        <td valign="top" width="363"><strong><font color="#ff0000">padding(5)</font></strong></td>     </tr>   </tbody></table>  <p align="justify">As the diagram shows, the entire size of <strong>SpecialThreadPool </strong>should be 0x80 (0x78 + 0x8) bytes. 0xb (11) bytes out of 0x80 are just padding. Furthermore, it is clear that the packing size of <strong>SpecialThreadPool</strong> is 8 because every data field of <strong>SpecialThreadPool</strong> is aligned at multiple of 8 bytes. </p>  <p align="justify">Compare this value with the size <strong>0x75</strong> reported by debugger, the difference is just 0xb (0x80 - 0x75). It is the same as the number of&#160; padding bytes. So it seems that the packing reported by debugger is just 1 (no padding), not 8.</p>  <p align="justify">At this point, with all the information uncovered by using debugger, it is easy to locate the root cause by just doing a simple code review. It turns out that type <strong>SpecialThreadPool</strong> and type <strong>CGenericThreadPool </strong>were using different packing size in spite of having an inheritance relationship.&#160; In one of the header files that <strong>SpecialThreadPool</strong> includes, there is a line “#pragma pack(1)” which tells the complier to compile <strong>SpecialThreadPool</strong> using 1 as pack size. All the other classes are compiled with default pack size 8. This mistake in code cause the compiler to generate inconsistent code regarding the size of <strong>SpecialThreadPool</strong> type, which in turn results the heap buffer overrun in runtime.</p>  <p align="justify"><em><strong><font size="3">Take Away:</font></strong></em> </p>  <p align="justify">The techniques shown in this case study is based on some fundamental understanding of how the memory is used in Windows. As a software developer, it is important to understand data structure memory layout and language object model, although most time the complier has abstracted this information away. These knowledge can comes handy while debugging memory relative debugs. </p>  <p align="justify">Besides packing, there are many other aspects of compiler can be configured and they would affect the final shape of the generated codes. When making setting changes in the code, it is recommended to localize its effect by saving and restore the original value. For example, instead of just throw “#pragma pack(1)” into some header file, it is better to use the following code:</p>  <p><font color="#8080c0"><strong><font face="Courier New"><font color="#008000">#pragma</font> <font color="#000000">pack(push)&#160; </font><font color="#004000">//to save current packing size</font>&#160; </font></strong></font></p>  <p><font color="#8080c0"><strong><font face="Courier New"><font color="#008000">#pragma</font> <font color="#000000">pack(1)</font>&#160;&#160;&#160;&#160; <font color="#004000">//enable special packing, no padding</font></font></strong></font> </p>  <p><font color="#8080c0"><strong><font face="Courier New"><font color="#000000">...</font>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="#004000">//your data structure here</font></font></strong></font> </p>  <p><font color="#8080c0"><strong><font face="Courier New"><font color="#008000">#pragma</font> <font color="#000000">pack(pop)</font>&#160;&#160; <font color="#004000">//restore the packing size to original value</font></font></strong></font> </p>  <p>This way, other files will not accidentally inherit this special packing setting when including this header file. On the other hand, if the setting changes are meant to be global, it is better to make those changes in complier level (like complier switchers), not in the code itself. </p>  <p><em><strong><font size="3">References:</font></strong></em></p>  <p>1. <strong><a href="http://msdn.microsoft.com/en-us/library/2e70t5y1.aspx">[MSDN-PACK] Pack</a></strong></p>  <p>2. <a href="http://www.amazon.com/Windows-via-Pro-Jeffrey-Richter/dp/0735624240">[WVC07] Windows via C/C++, Fifth Edition</a> Chapter 8.2</p>  <p>3. <a href="http://www.amazon.com/Principles-Parallel-Programming-Calvin-Lin/dp/0321487907/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1273529408&amp;sr=1-1">[PPP09] Principles of Parallel Programming</a> Chapter 1</p>  <p>4. <strong><a href="http://www.amazon.com/Inside-Object-Model-Stanley-Lippman/dp/0201834545">[ICOM96] Inside the C++ Object Model</a></strong></p>  <p>&#160;</p>  <p><strong><font size="3">Special thanks to <font color="#0080c0">Gabriel</font> and <font color="#0080c0">Daniel</font>’s help in finding this bug in the first place</font></strong></p>]]></content:encoded>
    </item>
    <item>
      <title>Windows Heap Overrun Monitoring</title>
      <link>https://docs.microsoft.com/archive/blogs/jiangyue/windows-heap-overrun-monitoring</link>
      <pubDate>Mon, 15 Mar 2010 18:51:00 GMT</pubDate>
      <dc:creator><![CDATA[Brandon Jiang]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/jiangyue/2010/03/15/windows-heap-overrun-monitoring/</guid>
      <description><![CDATA[Heap is one of the most important memory structures used by almost every programs. Windows Heap...]]></description>
      <content:encoded><![CDATA[<p align="justify">Heap is one of the most important memory structures used by almost every programs. Windows Heap Manager is at core of heap management. In this blog, I would like to focus on the heap monitoring feature provided by Windows Heap Manager and some other useful tools in the context of detecting heap overrun. All the examples are based on 64-bit Windows 7 Operating System. The memory structures and layouts in 32-bit OS are similar to 64-bit ones, usually it’s just&#160; the size difference (which is half of the 64-bit ones).</p>  <p align="justify"><em><font color="#004080">Note: A major revamp has done to Windows Heap Manager in Windows Vista and continued in Windows 7. The purpose of those changes is to improve Heap Manager’s performance, security and error resilience and monitoring. There are many great books and articles online about the details of latest Windows Heap Manager, such like <a href="http://www.amazon.com/Advanced-Windows-Debugging-Mario-Hewardt/dp/0321374460" target="_blank" mce_href="http://www.amazon.com/Advanced-Windows-Debugging-Mario-Hewardt/dp/0321374460"><em>[AWD07]</em></a> and <a href="http://www.microsoft.com/learning/en/us/book.aspx?ID=12069&amp;locale=en-us" target="_blank" mce_href="http://www.microsoft.com/learning/en/us/book.aspx?ID=12069&amp;locale=en-us"><em>[WININT09]</em></a>.&#160; </font></em></p>  <p align="justify"><em><font color="#004080"></font></em></p>  <p align="justify"><em><font color="#004080"></font></em></p>  <p align="justify"><strong><font size="3"><em>Standard Heap Monitoring by Windows Heap Manager</em></font></strong> </p>  <p align="justify">Windows Heap Manager provides some basic heap monitoring functionalities for every programs using heap.&#160; It performs limited heap validation in many heap operations. The normal heap block layout managed by Windows Heap Manager looks like this:</p>  <table border="0" cellspacing="0" cellpadding="2" width="503"><tbody>     <tr>       <td valign="top" width="226"><strong>Heap Block</strong> </td>        <td valign="top" width="265"><strong>|Next Heap Block</strong></td>        <td valign="top" width="10"><strong>…</strong></td>     </tr>   </tbody></table>  <table border="1" cellspacing="0" cellpadding="2" width="487"><tbody>     <tr>       <td valign="top" width="84" align="center"><em>Heap Header</em></td>        <td valign="top" width="142" align="center"><strong><em>User Allocation</em></strong> </td>        <td valign="top" width="82" align="center"><em>Heap Header</em></td>        <td valign="top" width="177" align="center"><strong><em>User Allocation</em></strong> </td>     </tr>   </tbody></table>  <table border="0" cellspacing="0" cellpadding="2" width="487"><tbody>     <tr>       <td valign="top" width="84" align="center"><font size="1"><em>16 bytes</em></font></td>        <td valign="top" width="143" align="center"><font size="1"><em>Multiple of 16 bytes</em></font> </td>        <td valign="top" width="82" align="center"><font size="1"><em>16 bytes</em></font></td>        <td valign="top" width="176" align="center"><font size="1"><em>Multiple of 16 bytes</em></font> </td>     </tr>   </tbody></table>  <p align="justify">As you can imagine, if the memory-write overruns the user allocated portion, then the next heap block’s header will be overwritten. Windows Heap Manager validates the heap header every time when a heap block is used or freed. If it finds the header has been damaged, then it announces a heap overrun has happened. Because of this detection mechanism used by Windows Heap Manager, it is not able to catch the overrun at the time it happens, but only detect it afterwards when the corrupted block is involved in some other operations.</p>  <p align="justify">Another important aspect here is that the size of user allocation space is always a multiple of 16 bytes. This means, even if the size of memory requested by user is just 1 byte, the Windows Heap manager will still allocate 16 bytes for that request, in which 15 bytes are marked as unused. In this case, if the overrun happens within the unused user allocation, then obviously the next heap block’s header will not be damaged. Thus, the Windows Heap Manager is not able to detect this kind of overrun.&#160; </p>  <p align="justify">Example 1:</p>  <p align="justify">The following code request a 1 byte memory using <strong>malloc</strong> function of Microsoft C Runtime Library (Release Build). <strong>malloc</strong> internally calls the Windows Heap Manager APIs to full fill the request. Once the memory is obtained, it initializes the 1 byte value to ‘a’, and after that, it overruns the heap with a wild assignment.&#160; </p> <font color="#004000">   <p><strong>&#160;&#160;&#160; char* a = (char *) malloc(1);        <br />&#160;&#160;&#160; a[0] = 'a'; a[24] = 'a';</strong></p> </font>  <p>Debugger was attached once the program starts, and the following debugger output shown is after the <strong>malloc </strong>call: </p>  <p><em><font color="#004080">Note: Do not use the debugger to launch the example program, the reason will be explained shortly. Also, the debugger needs to able to find the correct symbols for some of system DLLs, and the easiest way is to add Microsoft Public Symbol Server to the sympath</font></em></p>  <p><font color="#004000" face="Lucida Console">example1!wmain+0x91:      <br />00000001`3ff010c1 ff1571100000&#160;&#160;&#160; call&#160;&#160;&#160; qword ptr [example1!_imp_malloc (00000001`3ff02138)] ds:00000001`3ff02138={MSVCR100!malloc (00000000`510c89ec)}       <br /><strong><font color="#000000" face="Verdana">0:000&gt; p</font></strong>       <br /><font color="#ff0000">rax=00000000003897b0</font> rbx=00000000003ae590 rcx=0000000000000003       <br />rdx=00000000003897b0 rsi=00000000003ae570 rdi=00000000003ae5b0       <br />rip=000000013fb410c7 rsp=000000000030fa40 rbp=0000000000000000       <br />r8=0000000000000000&#160; r9=0000000000000000 r10=0000000000000080       <br />r11=0000000000000000 r12=0000000000000000 r13=0000000000000000       <br />r14=0000000000000000 r15=0000000000000000       <br />iopl=0&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; nv up ei pl nz na po nc       <br />cs=0033&#160; ss=002b&#160; ds=002b&#160; es=002b&#160; fs=0053&#160; gs=002b&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; efl=00000206</font>     <br /><font color="#004000" face="Lucida Console">example1!wmain+0x97:      <br />00000001`3ff010c7 b910000000&#160;&#160;&#160;&#160;&#160; mov&#160;&#160;&#160;&#160; ecx,18h</font></p>  <p>In Windows 64 bit calling convention, the <strong>rax</strong> stores the return address of <strong>malloc</strong> function, i.e. address to the memory requested.</p>  <p><em><font color="#004080">Note: </font></em><em><font color="#004080">For the completed guide of calling conversion, please see <a href="http://www.agner.org/optimize/calling_conventions.pdf" mce_href="http://www.agner.org/optimize/calling_conventions.pdf">[FOGA10]</a>&#160;</font></em></p>  <p>To find more information about the heap block the returned address belongs to, use <strong>!heap –x</strong> command on the address in <strong>rax.</strong> it will find the heap block contains that particular address: </p>  <p><strong>0:000&gt; !heap -x <font color="#ff0000">00000000003897b0</font></strong>     <br /><font color="#004000" face="Lucida Console">Entry&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; User&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Heap&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Segment&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Size&#160; PrevSize&#160; Unused&#160;&#160;&#160; Flags      <br />-------------------------------------------------------------------------------------------------------------       <br /><font color="#8000ff">00000000003897a0</font>&#160; <font color="#ff0000">00000000003897b0</font>&#160; 0000000000380000&#160; 0000000000380000&#160;&#160;&#160;&#160;&#160;&#160;&#160; 20&#160;&#160;&#160;&#160;&#160; 1010&#160;&#160;&#160;&#160;&#160;&#160;&#160; 1f&#160; busy</font> </p>  <p align="justify">So we can see now, this heap block starting at <font color="#8000ff">00000000003897a0</font> with its header, then followed by the user allocation portion from <font color="#ff0000">00000000003897b0</font>, which is also the result address in <strong>rax</strong>. And the size of this block is 20 bytes and only 1 bytes is used so there are 1f bytes unused. We will see in a bit how those numbers come around. And the block is marked as busy because it is allocated.</p>  <p align="justify">We can even get much more information about the heap block and its neighboring heap blocks by using <strong>!heap –i </strong>command on the block entry address:</p>  <p><strong>0:000&gt; !heap -i <font color="#8000ff">00000000003897a0</font></strong>&#160; <br /><font color="#004000" face="Lucida Console">Detailed information for block entry 00000000003897a0      <br />Assumed heap&#160;&#160;&#160;&#160;&#160;&#160; : 0x0000000000380000 (Use !heap -i NewHeapHandle to change)       <br />Header content&#160;&#160;&#160;&#160; : 0x791E4849 0x1F00F699 (decoded : 0x03010002 0x1F000101)       <br />Owning segment&#160;&#160;&#160;&#160; : 0x0000000000380000 (offset 0)       <br />Block flags&#160;&#160;&#160;&#160;&#160;&#160;&#160; : 0x1 (busy )       <br />Total block size&#160;&#160; : 0x2 units (0x20 bytes)       <br />Requested size&#160;&#160;&#160;&#160; : 0x1 bytes (unused 0x1f bytes)       <br />Previous block size: 0x101 units (0x1010 bytes)       <br />Block CRC&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; : OK - 0x3&#160; <br />Previous block&#160;&#160;&#160;&#160; : 0x0000000000388790       <br />Next block&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; : <font color="#ff8000">0x00000000003897c0</font></font></p>  <p>It shows additional stuff like header content and next heap block (at address <font color="#ff8000">0x00000000003897c0)</font>.&#160; In order to get a better view of the heap block’s memory layout, let’s do a direct memory dump at the beginning of the heap block:</p>  <p><strong>0:000&gt; dc <font color="#8000ff">00000000003897a0</font></strong>&#160; <br /><font color="#004000"><font face="Lucida Console"><font color="#8000ff">00000000`003897a0&#160; 00000000 00000000 791e4849 1f00f699</font>&#160; ........IH.y....         <br /><font color="#0080ff">00000000`003897b0&#160; 003ae5d0 00000000 00380158 00000000</font>&#160; ..:.....X.8.....         <br /><font color="#ff8000">00000000`003897c0&#160; 00000000 00000000 fa1f48cb 0000f79a</font>&#160; .........H......         <br />00000000`003897d0&#160; 003ae5d0 00000000 00380158 00000000&#160; ..:.....X.8.....</font></font></p>  <p align="justify">16 bytes value start from address <font color="#8000ff">00000000003897a0 </font>is the head header. You can see the same memory content <font color="#8000ff">791e4849 1f00f699</font> is shown in the result of !heap –i command above as header content. After the header, it follows with 16 bytes user allocation space (starting at<font color="#ff0000"> </font><font color="#0080c0">00000000`003897b0</font>). Although only 1 byte is requested by the user, the Windows Heap Manager still reserves 16 bytes memory space for that request. After the user allocation space, the next memory address <font color="#ff8000">00000000`003897c0 </font>is actually the address of next heap block (the 16 bytes value from <font color="#ff8000">00000000`003897c0 </font>contains the next block’s header). So, we can do the following math: </p>  <ul>   <li>Total block size = size of header + size of user allocation = 0x20 (32) bytes </li>    <li>User allocation size = 0x10 (16) bytes, in which, 1 bytes is used (requested), 0x20 – 1 = 0x1F (31) bytes are unused. The unused bytes actually include the unused part of user allocation plus the block header which is not accessible to the user. </li> </ul>  <p align="justify">Let’s continue with the code execution,&#160; <font color="#004000"><strong>a[0] = 'a'; </strong></font>this is a valid heap usage because it matches the 1 byte requested space. After this assignment, the memory looks like this:</p> <strong>0:000&gt; dc <font color="#8000ff">00000000003897a0</font></strong>&#160; <br /><font color="#004000"><font face="Lucida Console"><font color="#8000ff">00000000`003897a0&#160; 00000000 00000000 791e4849 1f00f699</font>&#160; ........IH.y....       <br /><font color="#ff0000"><font color="#0080ff">00000000`003897b0&#160; 003ae5</font><strong>61</strong> </font><font color="#0080ff">00000000 00380158 00000000</font>&#160; <strong><font color="#ff0000">a</font></strong>.:.....X.8.....       <br /><font color="#ff8000">00000000`003897c0&#160; 00000000 00000000 fa1f48cb 0000f79a</font>&#160; .........H......       <br />00000000`003897d0&#160; 003ae5d0 00000000 00380158 00000000&#160; ..:.....X.8.....</font></font>   <p>So far so good. However, the upcoming assignment, <font color="#004000"><strong>a[24] = 'a';</strong></font>, is totally out of line. It is way beyond the requested memory size. After executing this wild code, the memory looks like this now:</p> <strong>0:000&gt; dc <font color="#8000ff">00000000003897a0</font></strong>&#160; <br /><font color="#004000"><font face="Lucida Console"><font color="#8000ff">00000000`003897a0&#160; 00000000 00000000 791e4849 1f00f699</font>&#160; ........IH.y....       <br /><font color="#ff0000">00000000`003897b0&#160; 003ae561 00000000 00380158 00000000</font>&#160; a.:.....X.8.....       <br /><font color="#ff8000">00000000`003897c0&#160; 00000000 00000000 fa1f48<strong><font color="#ff0000">61</font></strong> 0000f79a</font>&#160; ........<font color="#ff0000"><strong>a</strong></font>H......       <br />00000000`003897d0&#160; 003ae5d0 00000000 00380158 00000000&#160; ..:.....X.8.....</font></font>   <p>As you can see,&#160; the last assignment overrides the header value of next heap block. It broke the coherence of heap structures, and later on if the damaged heap block is involved in some other memory operation, the Windows Heap Manager will detect this error. The following error occurs once the program is allowed to continue execution: </p>  <p><strong>0:000&gt; g      <br /></strong><font color="#004000" face="Lucida Console">Critical error detected <font color="#ff0000">c0000374</font>       <br />(c78.19c8): Break instruction exception - code 80000003 (first chance)       <br />ntdll!RtlReportCriticalFailure+0x2f:       <br />00000000`77a26c9f cc&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; int&#160;&#160;&#160;&#160; 3</font></p>  <p><strong>0:000&gt; !heap</strong>     <br /><font color="#004000" face="Lucida Console">Details: </font></p>  <p><font color="#004000" face="Lucida Console">Error address: <font color="#ff8000">00000000003897c0</font>       <br />Heap handle: 0000000000380000       <br /><font color="#ff0000">Error type heap_failure_buffer_overrun (6)</font>       <br />Parameter 1: 000000000000000a       <br />Last known valid blocks: before - 00000000003897a0, after - 0000000000389fc0       <br />Stack trace:       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 0000000077a2a4a8: ntdll!RtlpAnalyzeHeapFailure+0x00000000000003a8       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 00000000779bea71: ntdll!RtlpAllocateHeap+0x0000000000002176       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 00000000779b29ac: ntdll!RtlAllocateHeap+0x000000000000016c       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 00000000779936ba: ntdll!RtlpAllocateUserBlock+0x0000000000000145       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 0000000077992b5b: ntdll!RtlpLowFragHeapAllocFromContext+0x00000000000004e7       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 00000000779b1c58: ntdll!RtlAllocateHeap+0x00000000000000e4       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="#ff0000">0000000078d48a47: MSVCR100!malloc+0x000000000000005b</font>       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 000000013fb410dc: example1!wmain+0x00000000000000ac       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 000000013fb4139e: example1!__tmainCRTStartup+0x000000000000011a       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 000000007785f56d: kernel32!BaseThreadInitThunk+0x000000000000000d       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 0000000077993281: ntdll!RtlUserThreadStart+0x000000000000001d       <br />Index&#160;&#160; Address&#160; Name&#160;&#160;&#160;&#160;&#160; Debugging options enabled       <br />&#160; 1:&#160;&#160; 00080000&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />&#160; 2:&#160;&#160; 00010000&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />&#160; 3:&#160;&#160; 00020000&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />&#160; 4:&#160;&#160; 00380000</font> </p>  <p align="justify">Therefore,<strong> the heap manager found this heap overrun error</strong> later on down the road, while it was trying to use the damaged heap block (<font color="#ff8000">00000000003897c0</font>) to full fill another memory allocation request. </p>  <p align="justify"><em><font color="#004080">Note: error code <strong><font color="#ff0000">0xc0000374 </font></strong> means&#160; <strong>STATUS_HEAP_CORRUPTION</strong>. </font></em><em><font color="#004080">It is a new error code added in Windows Vista. It is defined in header file ntstatus.h included in Windows SDK. The completed guild of Windows Error Code can be found at <a href="http://msdn.microsoft.com/en-us/library/cc231196(v=PROT.10).aspx">[MS-ERREF]</a>.</font></em></p>  <p align="justify">However, if we change the last assignment from&#160; <font color="#004000"><strong>a[24] = 'a';</strong></font> to <font color="#004000"><strong>a[1] = 'a';</strong></font>, What then? It is still a heap overrun error because <font color="#004000"><strong>a[1]</strong></font> exceeds the 1 bytes limit as well, although it is not as wild as <font color="#004000"><strong>a[24]</strong></font>.&#160; Can the Windows Heap Manager still catch this error?</p>  <p align="justify"><strong>0:000&gt; dc <font color="#8000ff">00000000003897a0</font></strong>&#160; <br /><font color="#004000"><font face="Lucida Console"><font color="#8000ff">00000000`003897a0&#160; 00000000 00000000 791e4849 1f00f699</font>&#160; ........IH.y....         <br /><font color="#ff0000">00000000`003897b0&#160; 003a<strong>6161</strong> 00000000 00380158 00000000</font>&#160;<strong><font color="#ff0000">a</font></strong><strong><font color="#ff0000">a</font></strong>:.....X.8.....         <br /><font color="#ff8000">00000000`003897c0&#160; 00000000 00000000 fa1f48cb 0000f79a</font>&#160; .........H......         <br />00000000`003897d0&#160; 003ae5d0 00000000 00380158 00000000&#160; ..:.....X.8.....</font></font> </p>  <p align="justify">The answer is no. <strong>Windows Heap Manager cannot detect this variant of overrun error</strong> because the overrun is within the unused user allocation of heap block. As shown above, the next heap block’s header is still intact and there is no way for Windows Heap Manager to notice any problems. For this simple example, it got lucky and it can continue execution to exit without any more problems, but for many other applications, this kind of heap overrun just like a time bomb waiting there to cause bigger problems.</p>  <p align="justify">Is there a way to catch this kind of just off by 1 overrun?</p>  <p align="justify"><strong><font size="3"><em>Special Debug Heap Monitoring</em></font></strong> </p>  <p align="justify">Instead of using the standard heap, Windows Heap Manager uses a special debug heap for the processes that launched by debugger. This debug heap has a different heap block layout: </p>  <table border="0" cellspacing="0" cellpadding="2" width="885"><tbody>     <tr>       <td valign="top" width="426"><strong>Heap Block</strong> </td>        <td valign="top" width="440"><strong>|Another Heap Block</strong></td>        <td valign="top" width="17"><strong>…</strong></td>     </tr>   </tbody></table>  <table border="1" cellspacing="0" cellpadding="2" width="863"><tbody>     <tr>       <td valign="top" width="83" align="center"><em>Heap Header</em></td>        <td valign="top" width="135" align="center"><strong><em>User Allocation</em></strong> </td>        <td valign="top" width="138" align="center"><em>Tail Checking Pattern</em></td>        <td valign="top" width="73" align="center"><em>Heap Extra</em></td>        <td valign="top" width="85" align="center"><em>Heap Header</em></td>        <td valign="top" width="138" align="center"><strong><em>User Allocation</em></strong> </td>        <td valign="top" width="136" align="center"><em>Tail Checking Pattern</em></td>        <td valign="top" width="73" align="center"><em>Heap Extra</em></td>     </tr>   </tbody></table>  <table border="0" cellspacing="0" cellpadding="2" width="864"><tbody>     <tr>       <td valign="top" width="85" align="center"><font size="1"><em>16 bytes</em></font></td>        <td valign="top" width="135" align="center"><font size="1"><em>Multiple of 16 bytes</em></font> </td>        <td valign="top" width="137" align="center"><font size="1"><em>16 bytes</em></font></td>        <td valign="top" width="73" align="center"><font size="1"><em>16<font size="1"><em>–31</em></font> bytes</em></font></td>        <td valign="top" width="85" align="center"><font size="1"><em>16 bytes</em></font></td>        <td valign="top" width="138" align="center"><font size="1"><em>Multiple of 16 bytes</em></font> </td>        <td valign="top" width="135" align="center"><font size="1"><em>16 bytes</em></font></td>        <td valign="top" width="74" align="center"><font size="1"><em>16<font size="1"><em>– 31</em></font> bytes</em></font></td>     </tr>   </tbody></table>  <p align="justify"><em><font color="#004080">Note: You can force a debugger launched process to use the standard heap instead of the special debug heap by setting <strong>_NO_DEBUG_HEAP</strong> environment variable to <strong>1</strong>, or the <strong>-hd</strong> debugger command-line option. By just attaching the debugger to an existing process, it will NOT change from the standard heap to the debugger heap. That’s why the debugger must be attached after the example program started in Example 1.</font></em></p>  <p align="justify">Comparing to the basic heap block created by standard heap, the debug heap added more data after user allocation portion of each heap block. First data after user allocation is the <strong>Tail Checking Pattern</strong>. The pattern is a 16 bytes of <strong>ab</strong> with potential padding which aligns on 16-byte boundary. After that, it is followed by heap extra data (it is 16&#160; bytes or more depends on padding). The Heap Manager will validate the Tail Checking Pattern on release of heap block to check if it has been changed by any heap overruns.</p>  <p align="justify">In the last example, the heap overrun within unused user heap space has slipped through the detection of Windows Heap Manager, but it will be caught by this special debugger heap because the <strong>Tail Checking Pattern</strong> covers unused portion of user space as well. The detection is still not in real time: The overrun can only be found when that heap block is released, not at the time it actually happened. </p>  <p align="justify">This detection mechanism works well if the overrun is a continuous one from user allocated space. However, if the memory-write jumps over the Tail Checking Pattern and lands before next head header (i.e. writes in the padding area or heap extra area), then the Tail Checking Pattern is left unchanged by this overrun. Therefore, for this kind of overrun, it cannot be detected by using the special debug heap. </p>  <p align="justify">Example 2:</p>  <p align="justify">The following code request a 24 byte memory using <strong>malloc</strong> function. After that, it tries to perform some heap operation to cause a heap overrun error. This time, we use debugger to launch this program.</p> <font color="#004000">   <p><strong>&#160;&#160;&#160; char* b = (char *) malloc(24);&#160; <br />&#160;&#160;&#160; b[24] = 'b'; free(b);</strong></p> </font>  <p align="justify">The memory layout of the heap block returned by <strong>malloc</strong> looks like this:</p>  <p><strong>0:000&gt; !heap -i 0000000000234bf0</strong>&#160; <br /><font color="#004000" face="Lucida Console">Detailed information for block entry 0000000000234bf0      <br />Assumed heap&#160;&#160;&#160;&#160;&#160;&#160; : 0x0000000000230000 (Use !heap -i NewHeapHandle to change)       <br />Header content&#160;&#160;&#160;&#160; : 0x60B63EB2 0x380068BC (decoded : 0x02070005 0x38000103)       <br />Owning segment&#160;&#160;&#160;&#160; : 0x0000000000230000 (offset 0)       <br />Block flags&#160;&#160;&#160;&#160;&#160;&#160;&#160; : 0x7 (busy extra fill )       <br />Total block size&#160;&#160; : 0x5 units (0x50 bytes)       <br />Requested size&#160;&#160;&#160;&#160; : 0x18 bytes (unused 0x38 bytes)       <br />Previous block size: 0x103 units (0x1030 bytes)       <br />Block CRC&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; : OK - 0x2&#160; <br />Previous block&#160;&#160;&#160;&#160; : 0x0000000000233bc0       <br />Next block&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; : 0x0000000000234c40</font> </p>  <p><strong>0:000&gt; dc 0000000000234bf0</strong>&#160; <br /><font color="#004000"><font face="Lucida Console"><font color="#8000ff">00000000`00234bf0&#160; feeefeee feeefeee 60b63eb2 380068bc</font>&#160; .........&gt;.`.h.8         <br /></font><font face="Lucida Console"><font color="#0000ff">00000000`00234c00&#160; baadf00d baadf00d baadf00d baadf00d&#160; ................          <br />00000000`00234c10&#160; baadf00d baadf00d</font> </font><font face="Lucida Console"><font color="#ff8000">abababab abababab&#160; ................          <br />00000000`00234c20&#160; abababab abababab</font> feeefeee feeefeee&#160; ................         <br /><font color="#0080c0">00000000`00234c30&#160; 00000000 00000000 00000000 00000000</font>&#160; ................         <br /><font color="#8000ff">00000000`00234c40&#160; feeefeee feeefeee b3b53e62 000069ba</font>&#160; ........b&gt;...i..         <br />00000000`00234c50&#160; 00237ee0 00000000 00230158 00000000&#160; .~#.....X.#.....         <br />00000000`00234c60&#160; feeefeee feeefeee feeefeee feeefeee&#160; ................</font></font></p>  <p align="justify">The heap header is still 16 bytes starting from address <font color="#8000ff">00000000`00234bf0</font>. Then it is followed by 32 bytes user allocation starting from <font color="#0000ff">00000000`00234c00</font>. The heap manager always allocated in multiple of 16 bytes, even if the user only requested 24 bytes. Next, the debug heap put 16-byte Tail Checking Pattern immediately after the last byte of used portion of user allocation space, which is from <font color="#ff8000">00000000`00234c18</font> to <font color="#ff8000">00000000`00234c27</font>. In order to get aligned at 16 bytes boundary, 8 bytes of padding is added after the Tail Checking Pattern. Lastly, there is another 16 bytes of heap extra starting from <font color="#0080c0">00000000`00234c30. </font>The next heap block starts next 16 bytes boundary (at address <font color="#8000ff">00000000`00234c40)</font>. </p>  <ul>   <li>Total block size = size of header + size of user allocation + Tail Checking Pattern + Padding + Heap Extra&#160; = 0x50 (80) bytes </li>    <li>User allocation size = requested size + extra filling = 0x40 (64) bytes, in which, 0x18 (24) bytes is used (requested), 0x50 – 0x18 = 0x38 (56) bytes are unused. </li> </ul>  <p align="justify">Let’s continue executing the next assignment statement <font color="#004000"><strong>a[24] = 'a';</strong></font>. This assignment overruns the allocated heap by 1 byte, hence, it modified the first byte of Tail Checking Pattern. The memory layout after the assignment looks like this:</p> <font color="#004000"><font face="Lucida Console"><font color="#8000ff">00000000`00234bf0&#160; feeefeee feeefeee 60b63eb2 380068bc</font>&#160; .........&gt;.`.h.8       <br /></font><font face="Lucida Console"><font color="#0000ff">00000000`00234c00&#160; baadf00d baadf00d baadf00d baadf00d&#160; ................        <br />00000000`00234c10&#160; baadf00d baadf00d</font> </font><font face="Lucida Console"><font color="#ff8000">ababab<strong><font color="#ff0000">62</font></strong> abababab&#160; ........<strong><font color="#ff0000">b</font></strong>.......         <br />00000000`00234c20&#160; abababab abababab</font> feeefeee feeefeee&#160; ................       <br /><font color="#0080c0">00000000`00234c30&#160; 00000000 00000000 00000000 00000000</font>&#160; ................       <br /><font color="#8000ff">00000000`00234c40&#160; feeefeee feeefeee b3b53e62 000069ba</font>&#160; ........b&gt;...i..       <br />00000000`00234c50&#160; 00237ee0 00000000 00230158 00000000&#160; .~#.....X.#.....       <br />00000000`00234c60&#160; feeefeee feeefeee feeefeee feeefeee&#160; ................</font></font>   <p>We have created a heap overrun just by 1 byte, just like we did in the last part of example 1. It is well within the unused user allocation space. Let the program to continue:</p>  <p><strong>0:000&gt; g      <br /></strong><font color="#004000" face="Lucida Console"><font color="#ff0000">HEAP: Heap block at 0000000000234BF0 modified at 0000000000234C18 past requested size of 18</font>       <br />(2a54.1af0): Break instruction exception - code 80000003 (first chance)       <br />ntdll!RtlpBreakPointHeap+0x21:       <br />00000000`77a13741 cc&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; int&#160;&#160;&#160;&#160; 3</font>     <br /><strong>0:000&gt; k</strong>     <br /><font color="#004000" face="Lucida Console">Child-SP&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; RetAddr&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Call Site      <br />00000000`001cf678 00000000`77a225a1 ntdll!RtlpBreakPointHeap+0x21       <br />00000000`001cf680 00000000`779c887e ntdll!RtlpCheckBusyBlockTail+0x211       <br />00000000`001cf6c0 00000000`77a2c499 ntdll!RtlpValidateHeapEntry+0x45f0e       <br />00000000`001cf700 00000000`779cd0fe ntdll!RtlDebugFreeHeap+0xb9       <br />00000000`001cf760 00000000`779b2075 ntdll!RtlpFreeHeap+0x1b07e       <br />00000000`001cfaa0 00000000`77862c7a ntdll!RtlFreeHeap+0x1a2       <br />00000000`001cfb20 00000000`78d68ac4 kernel32!HeapFree+0xa       <br />00000000`001cfb50 00000001`3fd31152 MSVCR100!free+0x1c       <br />00000000`001cfb80 00000001`3fd3138e example2!wmain+0x122       <br />00000000`001cfbb0 00000000`7785f56d example2!__tmainCRTStartup+0x11a       <br />00000000`001cfbe0 00000000`77993281 kernel32!BaseThreadInitThunk+0xd       <br />00000000`001cfc10 00000000`00000000 ntdll!RtlUserThreadStart+0x1d</font></p>  <p align="justify">As you see<strong>, The debug heap has detected this off-by-1 overrun</strong>. The call stack shows that the error is found when heap is being released. Hence, the debug heap is able to catch overruns which are within the unused user allocation area. By the way, this detection is also postmortem in nature as you might already notice. </p>  <p align="justify">Let’s try something else now. If we change the assignment from <font color="#004000"><strong>a[24] = 'a';</strong></font> to <font color="#004000"><strong>a[40] = 'a';</strong></font>, then the memory-write skips over the Tail Checking Pattern and lands on the padding area, as shown on the memory layout below:</p> <font color="#004000"><font face="Lucida Console"><font color="#8000ff">00000000`00234bf0&#160; feeefeee feeefeee 60b63eb2 380068bc</font>&#160; .........&gt;.`.h.8       <br /></font><font face="Lucida Console"><font color="#0000ff">00000000`00234c00&#160; baadf00d baadf00d baadf00d baadf00d&#160; ................        <br />00000000`00234c10&#160; baadf00d baadf00d</font> </font><font face="Lucida Console"><font color="#ff8000">abababab abababab&#160; ................        <br />00000000`00234c20&#160; abababab abababab</font> feeefe<strong><font color="#ff0000">62</font></strong> feeefeee&#160; ........<strong><font color="#ff0000">b</font></strong>.......       <br /><font color="#0080c0">00000000`00234c30&#160; 00000000 00000000 00000000 00000000</font>&#160; ................       <br /><font color="#8000ff">00000000`00234c40&#160; feeefeee feeefeee b3b53e62 000069ba</font>&#160; ........b&gt;...i..       <br />00000000`00234c50&#160; 00237ee0 00000000 00230158 00000000&#160; .~#.....X.#.....       <br />00000000`00234c60&#160; feeefeee feeefeee feeefeee feeefeee&#160; ................</font></font>   <p align="justify">In this case, <strong>the Tail Checking Pattern is unchanged by the overrun, Thus, it cannot be detected by the debug heap.</strong> If the program is allowed to continuous, it will finish without rising any problems.</p>  <p align="justify">More interestingly, if the debug heap is not used (i.e. the program is not spawned by the debugger), this overrun, <font color="#004000"><strong>a[40] = 'a';</strong></font>, would have landed on the heap header of next heap block. And for that, the Windows Heap Manager could detect it. <strong>This should give you a basic idea on why having the debugger could make some of the heap corruption bug to disappear</strong>.</p>  <p align="justify"><strong><font size="3"><em>PageHeap Monitoring</em></font></strong> </p>  <p align="justify">So far we have seen the default Windows Heap Manager monitoring and detection ability, as well as the the ability of the special debug heap. However, both of them have certain limitations on detecting heap overruns. </p>  <p align="justify">To overcome those limitations, Microsoft has a tool called PageHeap which provides better heap monitoring and detection features than last two. As time of this writing, the PageHeap tool has been integrated into Gflags tool as well as AppVerifier tool. Its usage are well documented in MSDN and widely discussed in the community. Both books <a href="http://www.amazon.com/Advanced-Windows-Debugging-Mario-Hewardt/dp/0321374460" target="_blank" mce_href="http://www.amazon.com/Advanced-Windows-Debugging-Mario-Hewardt/dp/0321374460"><em>[AWD07]</em></a> and <a href="http://www.microsoft.com/learning/en/us/book.aspx?ID=12069&amp;locale=en-us" target="_blank" mce_href="http://www.microsoft.com/learning/en/us/book.aspx?ID=12069&amp;locale=en-us"><em>[WININT09]</em></a> have chapters on it too.</p>  <p align="justify">Using either Gflags or AppVerifier, a Full Page Heap layout can be enabled for each heap block as shown below</p>  <p align="justify"><a href="http://msdn.microsoft.com/en-us/library/ms220938(VS.80).aspx" mce_href="http://msdn.microsoft.com/en-us/library/ms220938(VS.80).aspx"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="Full page heap block structure" border="0" alt="Full page heap block structure" align="left" src="http://i.msdn.microsoft.com/ms220938.Local_-1265171613_fphbs(en-US,VS.80).gif" width="452" height="170" mce_src="http://i.msdn.microsoft.com/ms220938.Local_-1265171613_fphbs(en-US,VS.80).gif" /></a>&#160;</p>  <p align="justify"><em></em>&#160;</p>  <p align="justify"><em></em>&#160;</p>  <p align="justify"><em></em>&#160;</p>  <p align="justify"><em></em>&#160;</p>  <p align="justify">&#160;</p>  <p align="justify">&#160;</p>  <p align="justify"><em>Diagram source: <a href="http://msdn.microsoft.com/en-us/library/ms220938(VS.80).aspx" mce_href="http://msdn.microsoft.com/en-us/library/ms220938(VS.80).aspx">[MSDN-TSPHB]</a></em><em></a></em></p>  <p align="justify">And the actually memory layout for such a heap block looks like this (the debug output is showing a busy heap block):&#160; </p>  <p><font color="#004000"><font face="Lucida Console">0:000&gt; dc 3e50ff0-40        <br /></font><font face="Lucida Console">00000000`03e50fb0&#160; abcdbbbb 00000000 03d21000 00000000&#160; ................        <br />00000000`03e50fc0&#160; 00000001 00000000 00001000 00000000&#160; ................         <br />00000000`03e50fd0&#160; 00000000 00000000 00000000 00000000&#160; ................         <br />00000000`03e50fe0&#160; 00227e70 00000000 00000000 dcbabbbb&#160; p~&quot;.............         <br /><font color="#ff00ff">00000000`03e50ff0&#160; d0d0d0c0 d0d0d0d0 d0d0d0d0 d0d0d0d0&#160; ................</font>         <br /></font><font color="#ff0000" face="Lucida Console">00000000`03e51000&#160; ???????? ???????? ???????? ????????&#160; ????????????????        <br />00000000`03e51010&#160; ???????? ???????? ???????? ????????&#160; ????????????????         <br />00000000`03e51020&#160; ???????? ???????? ???????? ????????&#160; ????????????????</font></font> </p>  <p align="justify">The <font color="#008000">green part</font> is the Prefix Pattern for that heap block starting with <font color="#008000">abcdbbbb</font> and ending with <font color="#008000">dcbabbbb</font>. Next, the <font color="#ff00ff">purple part</font> is the user allocation. There is 1 byte of <font color="#ff00ff">c0</font> and 15 bytes of <font color="#ff00ff">d0</font> in the user allocation, and that means the user only requested 1 byte of memory. The rest 15 bytes of <font color="#ff00ff">d0</font> are the suffix pattern. Lastly, it is the non-accessible page (<font color="#ff0000">the red part</font>) after the last <font color="#ff00ff">d0</font> . </p>  <p align="justify">Let’s assume <font color="#008000"><strong>char* a</strong></font> is pointed to the valid address of that 1 byte allocation. A heap overrun, such as a memory write to the address at <font color="#008000"><strong>a[24]</strong></font>, will immediately cause a access violation exception: </p>  <p><font color="#008000"><font face="Lucida Console"><font color="#004000">(297c.62c):</font> <font color="#ff0000">Access violation - code c0000005</font> <font color="#004000">(first chance)</font>         <br /></font><font face="Lucida Console"><font color="#004000">First chance exceptions are reported before any exception handling.          <br />This exception may be expected and handled.           <br />example1!wmain+0x19:</font>         <br /><font color="#ff0000">00000001`3f9a1019 c6401862&#160;&#160;&#160;&#160;&#160;&#160;&#160; mov&#160;&#160;&#160;&#160; byte ptr [rax+18h],62h ds:00000000`03e51008=??</font></font></font> </p>  <p align="justify">You can see the access violation happens at exact the same time the <strong><font color="#ff0000">mov</font></strong> instruction trying to access an address in the <font color="#ff0000">red part</font> of the memory layout. So first time ever, the heap overrun is caught right at when it happens. </p>  <p align="justify">But what if the heap overrun is within the suffix pattern, such as a off-by-1 overrun (a memory write to address at <font color="#008000"><strong>a[1])</strong></font>? In that case, the heap overrun will be detected only when that block is released. That’s when the suffix pattern validation is done, just like the debug heap. If the program is under debugger, the following error is shown when the program is trying to <strong><font color="#008000">free(a)</font></strong></p>  <p><font color="#008000" face="Lucida Console"><font color="#004000">===========================================================</font>       <br /><font color="#ff0000">VERIFIER STOP 000000000000000F: pid 0x2898: corrupted suffix pattern</font> </font></p>  <p><font color="#004000" face="Lucida Console">&#160;&#160;&#160; 0000000003F31000 : Heap handle      <br />&#160;&#160;&#160; 0000000004060FF0 : Heap block       <br />&#160;&#160;&#160; 0000000000000001 : Block size       <br />&#160;&#160;&#160; 0000000004060FF1 : corruption address</font> </p>  <p><em><font color="#004080">Note: When PageHeap is enabled, the Heap Stack Trace is also enable for every heap block. The Stack Trace records the entire call stack of last heap operation done to that heap block. For example, the <strong>!heap –p –a</strong> <strong>memory_address</strong> command finds the heap block contains the specific memory address, and it also displays the stack trace: </font></em></p>  <p><em><font color="#004080" face="Lucida Console">0:000&gt; !heap -p -a 0000000003E50FF0        <br />&#160;&#160;&#160; address 0000000003e50ff0 found in         <br />&#160;&#160;&#160; _DPH_HEAP_ROOT @ 3d21000         <br />&#160;&#160;&#160; in busy allocation (&#160; DPH_HEAP_BLOCK:&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; UserAddr&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; UserSize -&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; VirtAddr&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; VirtSize)         <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 3d24888:&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 3e50ff0&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 1 -&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 3e50000&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 2000         <br /><strong>&#160;&#160;&#160; 000007fef3198513 verifier!AVrfDebugPageHeapAllocate+0x000000000000026f          <br />&#160;&#160;&#160; 0000000077a39901 ntdll!RtlDebugAllocateHeap+0x0000000000000031           <br />&#160;&#160;&#160; 00000000779fe6ea ntdll!RtlpAllocateHeap+0x000000000004bd2a           <br />&#160;&#160;&#160; 00000000779b29ac ntdll!RtlAllocateHeap+0x000000000000016c           <br />&#160;&#160;&#160; 000000006e5f8a47 MSVCR100!malloc+0x000000000000005b           <br />&#160;&#160;&#160; 000000013fff1011 testprogram!wmain+0x0000000000000011           <br />&#160;&#160;&#160; 000000013fff1262 testprogram!__tmainCRTStartup+0x000000000000011a           <br />&#160;&#160;&#160; 000000007785f56d kernel32!BaseThreadInitThunk+0x000000000000000d           <br />&#160;&#160;&#160; 0000000077993281 ntdll!RtlUserThreadStart+0x000000000000001d</strong></font></em> </p>  <p><em><font color="#004080">From the stack trace, you can see the last operation is the allocation of that heap block.&#160; </font></em></p>  <p>Gflags and AppVerifier also provide a slimmed down version of Full Page Heap called Normal Page Heap. The difference is that Normal Page Heap doesn’t have the non-accessible page appended after the suffix pattern. Therefore, using Normal Page Heap, it is not possible to catch heap overrun instantly. </p>  <p><strong><font size="3"><em></em></font></strong></p>  <p><strong><font size="3"><em>Microsoft Visual Studio C Runtime (Debug Version)</em></font></strong></p>  <p>The debug version of Microsoft Visual Studio C Runtime library (msvcrtXXd) also has its own Heap monitoring feature. The mechanism it uses is similar to PageHeap.</p>  <p>&#160;&#160; </p>  <p><strong><font size="3"><em>Takeaways</em></font></strong></p>  <p align="justify">Windows Heap Manager provides different levels of heap monitoring in junction with debugger, gflags or AppVerifier. With PageHeap, a few overruns can be caught at the exact moment when it happens, but in most of time, the detection is only postmortem (i.e. the overrun is detected after it has happened). This nature of heap overrun make it become one of most difficult bug to solve. <a href="http://www.amazon.com/Advanced-Windows-Debugging-Mario-Hewardt/dp/0321374460" target="_blank" mce_href="http://www.amazon.com/Advanced-Windows-Debugging-Mario-Hewardt/dp/0321374460"><em>[AWD07]</em></a> has more information on how to deal with it and how to avoid the overrun at the first place. </p>  <p align="justify">Furthermore, having debugger might trigger Windows heap Manager to use debug heap, which has different heap block layout. This is a side effect of debugger. As demonstrated above, if the debugger is in the picture, this side effect could actually delays the exposure of certain heap corruption bugs and even prevents them from happening at all. <strong>Therefore, be careful, and always be aware of the implication of the environment the program is running under.</strong></p>  <p><em><strong><font size="3"></font></strong></em>&#160;</p>  <p><em><strong><font size="3"><font size="2">References</font>:</font></strong></em></p>  <p>1. <a href="http://www.amazon.com/Advanced-Windows-Debugging-Mario-Hewardt/dp/0321374460" target="_blank" mce_href="http://www.amazon.com/Advanced-Windows-Debugging-Mario-Hewardt/dp/0321374460">[AWD07] Advanced Windows Debugging</a> Chapter 6, Chapter 15</p>  <p>2. <a href="http://www.microsoft.com/learning/en/us/book.aspx?ID=12069&amp;locale=en-us" target="_blank" mce_href="http://www.microsoft.com/learning/en/us/book.aspx?ID=12069&amp;locale=en-us">[WININT09] Windows Internals, Fifth Edition</a> Chapter 9</p>  <p>3. <a href="http://msdn.microsoft.com/en-us/library/cc231196(v=PROT.10).aspx">[MS-ERREF] Windows Error Codes</a></p>  <p>4. <a href="http://www.agner.org/optimize/calling_conventions.pdf" mce_href="http://www.agner.org/optimize/calling_conventions.pdf">[FOGA10] Calling conventions for different C++ compilers and operating systems</a></p>  <p>5. <a href="http://msdn.microsoft.com/en-us/library/cc266933.aspx" mce_href="http://msdn.microsoft.com/en-us/library/cc266933.aspx">[MSDN-DTFW] Debugging Tools For Windows - !heap</a></p>  <p>6. <a href="http://msdn.microsoft.com/en-us/library/ms220938(VS.80).aspx" mce_href="http://msdn.microsoft.com/en-us/library/ms220938(VS.80).aspx">[MSDN-TSPHB] The Structure of a Page Heap Block</a></a></p>]]></content:encoded>
    </item>
    <item>
      <title>Case Study: How to debug 64-bit managed windows service at startup</title>
      <link>https://docs.microsoft.com/archive/blogs/jiangyue/case-study-how-to-debug-64-bit-managed-windows-service-at-startup</link>
      <pubDate>Sat, 20 Feb 2010 04:05:00 GMT</pubDate>
      <dc:creator><![CDATA[Brandon Jiang]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/jiangyue/2010/02/20/case-study-how-to-debug-64-bit-managed-windows-service-at-startup/</guid>
      <description><![CDATA[Sometimes you might need to debug a windows service which is written in managed code and it is...]]></description>
      <content:encoded><![CDATA[<p align="justify">Sometimes you might need to debug a windows service which is written in managed code and it is running on 64-bit windows, and to make the matter worse, the bug happens during the service startup. Without adding instrument codes into your binary, this could be a difficult setup to do debugging, because:</p>  <ol>   <li>     <div align="justify">Services Control Manager must start the service with the debugger attached. </div>   </li>    <li>     <div align="justify">Starting from Windows Vista/2008, all windows services are running under a separated session 0 (which has a different WindowStations/Desktop than the normal user interactive desktop). </div>   </li>    <li>     <div align="justify">The visual studio debugger cannot be attached in mixed mode (both native and managed) if the code is written prior to .NET 4.0</div>   </li> </ol>  <p align="justify">One solution for this problem is to use WinDBG debugger with SOS extension, and configure the “Image File Execution” options to start the service under debugger server automatically. The following case study demonstrates this technique. </p>  <p align="justify"><font size="3"><strong><em>The Bug</em></strong>:</font></p>  <p align="justify"><em><strong>ManagedService</strong></em> is a winidows service, its binary <strong><em>managedservice.exe</em></strong> is implemented using C#. The following error occurs when <em>ManagedService</em> is trying to start:</p>  <p><font color="#800000" size="1" face="Lucida Console">C:\Users\administrator&gt;net start ManagedService      <br />The ManagedService service is starting...       <br />The ManagedService service could not be started. </font></p>  <p><font color="#800000" size="1" face="Lucida Console">A system error has occurred. </font></p>  <p><font color="#800000" size="1" face="Lucida Console">System error 1067 has occurred. </font></p>  <p><font size="2" face="Vivaldi"><font color="#008040"><font color="#800000" size="1" face="Lucida Console">The process terminated unexpectedly.</font> </font></font></p>  <p>In Event Viewer (Windows Logs/Application), the actual CLR exception and call stack are recorded:</p>  <p><font color="#800000">System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.      <br />&#160;&#160; at System.Reflection.Module._GetTypesInternal(StackCrawlMark&amp; stackMark)       <br />&#160;&#160; at System.Reflection.Assembly.GetTypes()       <br />&#160;&#160; at MyCompany.MyProduct.IndigoSerializableObject.InitializeKnownTypesCache(List`1 assembliesToExamine)       <br />&#160;&#160; at MyCompany.MyProduct.ManagedService.OnStart(String[] args)</font> </p>  <p align="justify">This gives a better insight to the problem: This service was probably going to host some WCF services and maybe it was preloading some managed types to improve performance, and the CLR loader encountered an error while loading them. However, assuming there are quite few assemblies and each has a few types, this information alone is not enough to tell which exact type causes the error. What is really needed is the content of LoaderExceptions property so that we can pinpoint the guilty type.</p>  <p align="justify"><em><font color="#004080">Note: Fusion Log won’t help in this case, because it is a type loading exception not an assembly loading exception.</font></em></p>  <p align="justify"><em></em></p>  <p><em><strong><font size="3">The Debugging:</font></strong></em></p>  <p align="justify">First, We need to configure the service so that when it starts the debugger has already been attached. For that, we can use the “<strong><em>Image File Execution</em></strong>” option by specifying the “<strong><em>Debugger</em></strong>” entry. There are numerous blogs and technical articles detailed the usage of this. Basically what it does is to allow the debugger specified in the “<em>Debugger</em>” entry to launch first, and then the service process is in turn spawned by that debugger. </p>  <p align="justify">So which debugger we should use for “<em>Image File Execution</em>” option? Because all windows services are running under session 0 (Windows Vista/2008 above), whatever debugger we choose will also be spawned in session 0. If that debugger put out any GUIs, they will not be directly visible to the users (the “<em>Interactive Services Detection”</em> dialog box would pop up).&#160; In other words, any interactive debugger won’t be a good choice. Thus, what we actually need is to start a window-less debugger server instead, and then from the current user session, we can use an interactive debugger to connect to that server.</p>  <p align="justify">To setup the debugger server on service startup, we can use either <em><strong>gflags.exe</strong></em> or <em><strong>regedit.exe</strong></em> or other tools to configure the “<em>Debugger</em>” entry of&#160; “<em>Image file Execution</em>” option for <em>managedservice.exe</em> in the registry as:</p>  <p align="justify"><strong>%windbginstallpath%\cdb.exe –server tcp:port=1234 –c “g;”</strong></p>  <p align="justify"><em>%windbginstallpath%</em> is where the installation location of Debugging Tools for Windows, and the <em><strong>cdb.exe</strong></em> is the debugger which doesn’t create any new windows. The –<em>server </em>switch activate the debugger as debugger server, and <em>tcp:port=1234 </em>tells the debugger server to use TCP protocol and listening at port 1234 (you can use other protocol or port too, see debugger documentation).&#160; The last <em>–c ”g;” </em>switch tells the debugger to let <em>managedservice.exe</em> to continue to run upon attachment, and this is because we know the bug is unhandled exception and the exception will cause the debugger to break automatically. </p>  <p align="justify"><em><font color="#004080">Note: For investigating other kinds of bugs, different debugger commands can be appended after “g;” to enable debugger to act in various situations, for example, “g;sxe ld some.dll”, will break into the debugger automatically when some.dll is loaded into process space.</font></em>&#160;&#160; </p>  <p align="justify">Now, we restart the ManagedService again by typing </p>  <p align="justify"><strong>net start ManagedService</strong> </p>  <p align="justify">and then we start a new interactive debugger client <em><strong>ntsd.exe</strong> </em>(<em>cdb.exe or</em> <em>windbg.exe</em> also works) to connect to the debugger server:</p>  <p align="justify"><strong>%windbginstallpath%\ntsd.exe –remote tcp:server=localhost,port=1234</strong>&#160; </p>  <p align="justify">Here, the –remote switch activate the <em>ntsd.exe</em> as debug client, and <em>tcp:server=localhost,port=1234</em> tells the <em>ntsd.exe</em> to connect to the debugger server locally at port 1234 using TCP protocol.</p>  <p align="justify"><em><font color="#004080">Note: the Service Control manager has a default 30 seconds timeout period within which the service must have to start, otherwise it would ends the process and the attached debugger server. The timeout value can be adjusted by adding new DWORD value <strong>ServicesPipeTimeout</strong> under the following registry subkey:</font></em></p>  <p align="justify"><em><font color="#004080">HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control</font></em></p>  <p align="justify"><em><font color="#004080">Alternative, you can save a crash dump using .dump -ma command, and then debug the dump file in post mortem instead . –ma flag gives a memory dump with everything and it is required by SOS extension. </font></em></p>  <p>Once the ntsd.exe attached, we can see that the debugger has already break in because of the unhandled System.Reflection.ReflectionTypeLoadException. To save space, I only show the relevant parts of output from <em>ntsd.exe</em> window: </p>  <p><font color="#004000" face="Lucida Console">ModLoad: 000007fe`fac00000 000007fe`fac2d000&#160;&#160; C:\Windows\system32\ntmarta.dll      <br />ModLoad: 000007fe`fef50000 000007fe`fefa0000&#160;&#160; C:\Windows\system32\WLDAP32.dll       <br />(11f8.f58): CLR exception - code e0434f4d (first chance)       <br />CLR exception type: <font color="#ff0000">System.Reflection.ReflectionTypeLoadException</font>       <br />&#160;&#160;&#160; &quot;Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for m       <br />ore information.&quot;&#160; <br />00000000`7710017a c3&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ret       <br />DCMANAGER\administrator (tcp 127.0.0.1:50908) connected at Sat Feb 20 01:41:19 2010       <br />0:007&gt;</font></p>  <p>It’s time to take a closer look at the ReflectionTypeLoadException. To do that, we first need to load the SOS Debugger Extension. In the <em>ntsd.exe</em> window, type:</p>  <p><strong>.load %windir%\microsoft.net\&lt;architecture&gt;\&lt;version&gt;\sos.dll</strong></p>  <p>In my case, sos.dll is at c:\windows\Microsoft.NET\Framework64\v2.0.50727\. After SOS is loaded, we can use <em>!dso (!dumpstackobject)</em> to see all managed objects found within the bounds of the current stack, which will include our exception:</p>  <p><strong>0:007&gt;!dso</strong></p> <font color="#004000" face="Lucida Console">OS Thread Id: 0x14c4 (7)    <br />RSP/REG&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Object&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Name     <br />000000001b7382a0 00000000027cea38 System.Diagnostics.Process     <br />000000001b738450 00000000027cea38 System.Diagnostics.Process     <br />000000001b738458 00000000027ceb48 System.RuntimeType     <br />000000001b738468 00000000027ce868 System.Object     <br />000000001b7384e0 <u><font color="#ff0000">00000000027c9be0</font></u> System.Reflection.ReflectionTypeLoadException     <br />000000001b738510 00000000027c9be0 System.Reflection.ReflectionTypeLoadException     <br />000000001b738548 00000000027c9be0 System.Reflection.ReflectionTypeLoadException     <br />000000001b738550 00000000027c9be0 System.Reflection.ReflectionTypeLoadException     <br />000000001b738560 00000000027ca798 System.String     <br />000000001b738580 00000000027ca680 System.Object[]&#160;&#160;&#160; (System.Object[])     <br />000000001b7387c0 00000000027ca660 System.UnhandledExceptionEventArgs     <br />000000001b738b70 0000000002900760 System.Int32     <br />000000001b738b80 0000000002900760 System.Int32     <br />000000001b738bc8 0000000002900760 System.Int32</font>   <p>We can easily see that <font color="#ff0000">00000000027c9be0</font> is the object address of System.Reflection.ReflectionTypeLoadException. To see inside of that exception, we can use <em>!do (!dumpobject)</em> command:</p>  <p><strong>0:007&gt;!do</strong> <font color="#ff0000">00000000027c9be0</font> </p>  <p><font color="#004000" face="Lucida Console">Name: System.Reflection.ReflectionTypeLoadException      <br />MethodTable: 000007fef9730fc0       <br />EEClass: 000007fef8c3bd18       <br />Size: 152(0x98) bytes       <br />(C:\Windows\assembly\GAC_64\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)       <br />Fields:       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; MT&#160;&#160;&#160; Field&#160;&#160; Offset&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Type VT&#160;&#160;&#160;&#160; Attr&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Value Name       <br />000007fef8f3ec90&#160; 40000b5&#160;&#160;&#160;&#160;&#160;&#160;&#160; 8&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.String&#160; 0 instance 00000000027ca108 _className       <br />000007fef8f3d038&#160; 40000b6&#160;&#160;&#160;&#160;&#160;&#160; 10 ...ection.MethodBase&#160; 0 instance 000000000281de00 _exceptionMethod       <br />000007fef8f3ec90&#160; 40000b7&#160;&#160;&#160;&#160;&#160;&#160; 18&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.String&#160; 0 instance 0000000000000000 _exceptionMethodString       <br />000007fef8f3ec90&#160; 40000b8&#160;&#160;&#160;&#160;&#160;&#160; 20&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.String&#160; 0 instance 00000000027c9cd0 _message       <br />000007fef8f37b98&#160; 40000b9&#160;&#160;&#160;&#160;&#160;&#160; 28 ...tions.IDictionary&#160; 0 instance 0000000000000000 _data       <br />000007fef8f3ef58&#160; 40000ba&#160;&#160;&#160;&#160;&#160;&#160; 30&#160;&#160;&#160;&#160; System.Exception&#160; 0 instance 0000000000000000 _innerException</font></p>  <p><font color="#004000" face="Lucida Console">000007fef8f3ec90&#160; 40000bb&#160;&#160;&#160;&#160;&#160;&#160; 38&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.String&#160; 0 instance 0000000000000000 _helpURL      <br />000007fef8f3e580&#160; 40000bc&#160;&#160;&#160;&#160;&#160;&#160; 40&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Object&#160; 0 instance 00000000027ca4c8 _stackTrace       <br />000007fef8f3ec90&#160; 40000bd&#160;&#160;&#160;&#160;&#160;&#160; 48&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.String&#160; 0 instance 0000000000000000 _stackTraceString       <br />000007fef8f3ec90&#160; 40000be&#160;&#160;&#160;&#160;&#160;&#160; 50&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.String&#160; 0 instance 0000000000000000 _remoteStackTraceString       <br />000007fef8f45f00&#160; 40000bf&#160;&#160;&#160;&#160;&#160;&#160; 70&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Int32&#160; 1 instance&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 0 _remoteStackInex       <br />000007fef8f3e580&#160; 40000c0&#160;&#160;&#160;&#160;&#160;&#160; 58&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Object&#160; 0 instance 0000000000000000 _dynamicMethods </font></p>  <p><font color="#008000"><font face="Lucida Console"><font color="#004000">000007fef8f45f00&#160; 40000c1&#160;&#160;&#160;&#160;&#160;&#160; 74&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Int32&#160; 1 instance&#160;&#160;&#160;&#160;&#160; -2146232830 _HResult          <br />000007fef8f3ec90&#160; 40000c2&#160;&#160;&#160;&#160;&#160;&#160; 60&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.String&#160; 0 instance 0000000000000000 _source           <br />000007fef8f41698&#160; 40000c3&#160;&#160;&#160;&#160;&#160;&#160; 68&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.IntPtr&#160; 1 instance&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 0 _xptrs           <br />000007fef8f45f00&#160; 40000c4&#160;&#160;&#160;&#160;&#160;&#160; 78&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Int32&#160; 1 instance&#160;&#160;&#160;&#160;&#160;&#160; -532459699 _xcode           <br />000007fef8f34748&#160; 4000dad&#160;&#160;&#160;&#160;&#160;&#160; 80&#160;&#160;&#160;&#160;&#160; System.Object[]&#160; 0 instance 00000000027c6980 _classes           <br />000007fef8f34748&#160; 4000dae&#160;&#160;&#160;&#160;&#160;&#160; 88&#160;&#160;&#160;&#160;&#160; System.Object[]&#160; 0 instance</font> <u><font color="#ff0000">00000000027c9bb8</font></u> <u><font color="#ff0000">_exceptions</font></u></font></font></p>  <p align="justify">We are looking for the value of LoaderExceptions Property, and it is an array of exceptions, so that will be the last field <font color="#ff0000">_exceptions</font>. Its corresponding object address is <font color="#ff0000">00000000027c9bb8. </font>This field is an array, so we can see the actually memory layout of this array object by directly dump the memory content using <em>dd </em>command:</p>  <p><strong>0:007&gt;dd</strong> <font color="#ff0000">00000000027c9bb8</font></p>  <p><font color="#008000"><font face="Lucida Console"><font color="#004000">00000000`027c9bb8</font>&#160; <font color="#ff8040">f8f34748 000007fe</font> <font color="#0000a0">00000001 00000000</font>         <br /><font color="#004040">00000000`027c9bc8</font>&#160; <font color="#800080">f8f3ef58 000007fe</font> <font color="#ff0000">027c8538 00000000</font>         <br /></font><font color="#004000" face="Lucida Console">00000000`027c9bd8&#160; 00000000 08000004 f9730fc0 000007fe        <br />00000000`027c9be8&#160; 027ca108 00000000 0281d720 00000000         <br />00000000`027c9bf8&#160; 00000000 00000000 027c9cd0 00000000         <br />00000000`027c9c08&#160; 00000000 00000000 00000000 00000000         <br />00000000`027c9c18&#160; 00000000 00000000 027ca4c8 00000000         <br />00000000`027c9c28&#160; 00000000 00000000 00000000 00000000</font></font></p>  <p align="justify">The first 2 DWORDs together <font color="#ff8040">000007fe<font color="#ff8040">f8f34748 </font></font>is the address of method table of array type, and then the following 2 DWORDs together <font color="#0000a0">00000000</font><font color="#0000a0">00000001 </font>is number of elements in the array (which is 1 in this case), and then the next 2 DWORDs <font color="#800080">000007fe<font color="#800080">f8f3ef58 </font></font>is the address of method table of the type of element inside the array (which is the method table of exception). And lastly, the final 2 DWORDs <font color="#ff0000">00000000<font color="#ff0000">027c8538 </font></font>is the object address of the first element in the array, which is what we want! So, we use <em>!do</em> on that address:</p>  <p><strong>0:007&gt;!do</strong> <font color="#ff0000">00000000027c9bb8</font></p>  <p><font color="#004000" face="Lucida Console">Name: System.TypeLoadException      <br />MethodTable: 000007fef9718088       <br />EEClass: 000007fef8c308b0       <br />Size: 160(0xa0) bytes       <br />(C:\Windows\assembly\GAC_64\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)       <br />Fields:       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; MT&#160;&#160;&#160; Field&#160;&#160; Offset&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Type VT&#160;&#160;&#160;&#160; Attr&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Value Name       <br />000007fef8f3ec90&#160; 40000b5&#160;&#160;&#160;&#160;&#160;&#160;&#160; 8&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.String&#160; 0 instance 0000000000000000 _className       <br />000007fef8f3d038&#160; 40000b6&#160;&#160;&#160;&#160;&#160;&#160; 10 ...ection.MethodBase&#160; 0 instance 0000000000000000 _exceptionMethod       <br />000007fef8f3ec90&#160; 40000b7&#160;&#160;&#160;&#160;&#160;&#160; 18&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.String&#160; 0 instance 0000000000000000 _exceptionMethodString       <br />000007fef8f3ec90&#160; 40000b8&#160;&#160;&#160;&#160;&#160;&#160; 20&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.String&#160; 0 instance <u><font color="#ff0000">00000000027a8720</font></u> <font color="#ff0000">_message</font>       <br />000007fef8f37b98&#160; 40000b9&#160;&#160;&#160;&#160;&#160;&#160; 28 ...tions.IDictionary&#160; 0 instance 0000000000000000 _data       <br />000007fef8f3ef58&#160; 40000ba&#160;&#160;&#160;&#160;&#160;&#160; 30&#160;&#160;&#160;&#160; System.Exception&#160; 0 instance 0000000000000000 _innerException       <br />000007fef8f3ec90&#160; 40000bb&#160;&#160;&#160;&#160;&#160;&#160; 38&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.String&#160; 0 instance 0000000000000000 _helpURL       <br />000007fef8f3e580&#160; 40000bc&#160;&#160;&#160;&#160;&#160;&#160; 40&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Object&#160; 0 instance 0000000000000000 _stackTrace       <br />000007fef8f3ec90&#160; 40000bd&#160;&#160;&#160;&#160;&#160;&#160; 48&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.String&#160; 0 instance 0000000000000000 _stackTraceString       <br />000007fef8f3ec90&#160; 40000be&#160;&#160;&#160;&#160;&#160;&#160; 50&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.String&#160; 0 instance 0000000000000000 _remoteStackTraceString       <br />000007fef8f45f00&#160; 40000bf&#160;&#160;&#160;&#160;&#160;&#160; 70&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Int32&#160; 1 instance&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 0 _remoteStackIndex       <br />000007fef8f3e580&#160; 40000c0&#160;&#160;&#160;&#160;&#160;&#160; 58&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Object&#160; 0 instance 0000000000000000 _dynamicMethods       <br />000007fef8f45f00&#160; 40000c1&#160;&#160;&#160;&#160;&#160;&#160; 74&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Int32&#160; 1 instance&#160;&#160;&#160;&#160;&#160; -2146233054 _HResult       <br />000007fef8f3ec90&#160; 40000c2&#160;&#160;&#160;&#160;&#160;&#160; 60&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.String&#160; 0 instance 0000000000000000 _source       <br />000007fef8f41698&#160; 40000c3&#160;&#160;&#160;&#160;&#160;&#160; 68&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.IntPtr&#160; 1 instance&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 0 _xptrs       <br />000007fef8f45f00&#160; 40000c4&#160;&#160;&#160;&#160;&#160;&#160; 78&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Int32&#160; 1 instance&#160;&#160;&#160;&#160;&#160;&#160; -532459699 _xcode       <br />000007fef8f3ec90&#160; 40003b9&#160;&#160;&#160;&#160;&#160;&#160; 80&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.String&#160; 0 instance 00000000027a83e8 ClassName       <br />000007fef8f3ec90&#160; 40003ba&#160;&#160;&#160;&#160;&#160;&#160; 88&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.String&#160; 0 instance 00000000027a8468 AssemblyName       <br />000007fef8f3ec90&#160; 40003bb&#160;&#160;&#160;&#160;&#160;&#160; 90&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.String&#160; 0 instance 0000000000000000 MessageArg       <br />000007fef8f45f00&#160; 40003bc&#160;&#160;&#160;&#160;&#160;&#160; 7c&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Int32&#160; 1 instance&#160;&#160;&#160;&#160;&#160; -2146233054 ResourceId</font></p>  <p>And then we want to see the actually message. And <font color="#ff0000">_message</font> is just another String object, so we just need to use <em>!do</em> one more time:</p>  <p><strong>0:007&gt;!do</strong> <font color="#ff0000">00000000027a8720</font> </p>  <p><font color="#004000" face="Lucida Console">Name: System.String      <br />MethodTable: 000007fef8f3ec90       <br />EEClass: 000007fef8b4b038       <br />Size: 586(0x24a) bytes       <br />(C:\Windows\assembly\GAC_64\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)       <br />String: <font color="#ff0000">Could not load type MyCompany.MyProduct.TestImplementation.ITreeNode`1' from assembly 'TestImplementation</font>, Version=1.0.523.0, Culture=neutral, PublicKeyToken=9396306c2be7fcc4'.       <br />Fields:       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; MT&#160;&#160;&#160; Field&#160;&#160; Offset&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Type VT&#160;&#160;&#160;&#160; Attr&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Value Name       <br />000007fef8f45f00&#160; 4000096&#160;&#160;&#160;&#160;&#160;&#160;&#160; 8&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Int32&#160; 1 instance&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 281 m_arrayLength       <br />000007fef8f45f00&#160; 4000097&#160;&#160;&#160;&#160;&#160;&#160;&#160; c&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Int32&#160; 1 instance&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 179 m_stringLength       <br />000007fef8f406d8&#160; 4000098&#160;&#160;&#160;&#160;&#160;&#160; 10&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Char&#160; 1 instance&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 43 m_firstChar       <br />000007fef8f3ec90&#160; 4000099&#160;&#160;&#160;&#160;&#160;&#160; 20&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.String&#160; 0&#160;&#160; shared&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; static Empty       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &gt;&gt; Domain:Value&#160; 000000000009fba0:0000000002771308 &lt;&lt;       <br />000007fef8f40588&#160; 400009a&#160;&#160;&#160;&#160;&#160;&#160; 28&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Char[]&#160; 0&#160;&#160; shared&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; static WhitespaceChars       <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &gt;&gt; Domain:Value&#160; 000000000009fba0:0000000002771b28 &lt;&lt;</font></p>  <p align="justify">Mystery solved! it is the ITreeNode type from assembly TestImplementation giving us the trouble. Once we know about the exact type and assembly name, the rest of the debugging is just a piece of cake. Oh, btw, if you want to quit debugging, type single <em>'q'</em> to quit debugger client, or double &quot;qq&quot; to stop both debugger client and server.</p>  <p align="justify">It turned out this bug was actually caused by a mismatched version of assembly, and you probably has guessed it at the beginning.</p>  <p><em><strong><font size="3">Takeaway:</font></strong></em></p>  <p align="justify">All the techniques described above are very basic debugging tricks, including Image File Execution, Debugging Tools for Windows, debugger server and client, SOS extension and .NET object memory model. And you can find more details about each of them by searching their names on the Internet. In this blog, I have shown you how to use these techniques together to solve one particular bug, but of course, you can apply them together in many other creative ways to solve different bugs in various environment.</p>  <p>But I think the most important takeaway should be this: </p>  <p><strong>Make your startup logic as simple as possible! Less codes at startup == Less bugs at startup</strong></p>]]></content:encoded>
    </item>
  </channel>
</rss>