<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>voyce &#187; WinDbg</title>
	<atom:link href="http://www.voyce.com/index.php/category/software-development/windbg/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.voyce.com</link>
	<description>Programming and debugging tidbits</description>
	<lastBuildDate>Sun, 15 Jan 2012 13:10:46 +0000</lastBuildDate>
	
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Am I being called from DllMain?</title>
		<link>http://www.voyce.com/index.php/2011/08/20/am-i-being-called-from-dllmain/</link>
		<comments>http://www.voyce.com/index.php/2011/08/20/am-i-being-called-from-dllmain/#comments</comments>
		<pubDate>Sat, 20 Aug 2011 12:52:37 +0000</pubDate>
		<dc:creator>ian</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Visual Studio]]></category>
		<category><![CDATA[WinDbg]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://www.voyce.com/?p=1258</guid>
		<description><![CDATA[How can you tell if your code is being called from within DllMain? You could use an undocumented function from ntdll.dll.]]></description>
			<content:encoded><![CDATA[<p><div id="attachment_1265" class="wp-caption alignright" style="width: 210px"><a href="http://www.voyce.com/wp-content/uploads/2011/08/lock_200.png"><img src="http://www.voyce.com/wp-content/uploads/2011/08/lock_200.png" alt="Lock; literal images &#039;r&#039; us" title="lock_200" width="200" height="200" class="size-full wp-image-1265" /></a><p class="wp-caption-text">Lock; literal images 'r' us</p></div>While Googling for an obscure Windows function the other day, I came across <a href="http://www.geoffchappell.com/viewer.htm?doc=index.htm">this</a> fantastically useful repository of undocumented WinAPI functions, put together by Geoff Chappell. I&#8217;m not sure how I hadn&#8217;t discovered it before.</p>
<p>One of the functions that immediately caught my eye was <a href="http://www.geoffchappell.com/viewer.htm?doc=studies/windows/win32/ntdll/api/ldrapi/lockloaderlock.htm">LdrLockLoaderLock</a>. I&#8217;d previously spent quite a few frustrating hours trying to figure out how to determine whether some code was being executed from DllMain, i.e. while in the loader lock, so I could avoid doing anything dodgy &#8211; or indeed, anything at all. </p>
<p>The case I was looking at was some logging library code that was used, amongst other things, to record the fact that DLLs were being unloaded. Unfortunately when this was called from DllMain, it sometimes caused a deadlock, for all the reasons we already know about. The library code was called from lots of DLLs, so it wasn&#8217;t feasible to fix all of the call sites, instead I had to make the logging a no-op when it&#8217;s not safe.<br />
<span id="more-1258"></span><br />
I&#8217;m embarrassed to say that my previous attempt to detect the lock involved some pretty heinous hackery. I worked out the memory address (the offset within ntdll.dll) where the loader lock critical section is located, cast that bit of memory to a CRITICAL_SECTION and tested it. I even had to provide the ability to change the offset based on the version of ntdll being used, in a vain attempt to reduce its fragility. Ouch. It was very nasty, and to be honest although it worked in the cases where I tested it, I was reluctant to release it.</p>
<p>Luckily, along comes LdrLockLoaderLock to save my blushes. It appears to give me exactly the functionality I need; you can pass a flag to tell it to return immediately if the lock&#8217;s already been taken, and there&#8217;s a status parameter that can be used to tell if you got the lock &#8211; whereupon you can call the corresponding <a href="http://www.geoffchappell.com/viewer.htm?doc=studies/windows/win32/ntdll/api/ldrapi/unlockloaderlock.htm">LdrUnlockLoaderLock</a>. Nice!  </p>
<p>I wonder if this is what&#8217;s used by the Visual Studio <a href="http://msdn.microsoft.com/en-us/library/ms172219.aspx">loader lock managed debugging assistant</a> to determine if your managed code is being run under the loader lock?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.voyce.com/index.php/2011/08/20/am-i-being-called-from-dllmain/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>.NET 4.0 Type Equivalence causes BadImageFormatException</title>
		<link>http://www.voyce.com/index.php/2010/04/23/net-4-0-type-equivalence-causes-badimageformatexception/</link>
		<comments>http://www.voyce.com/index.php/2010/04/23/net-4-0-type-equivalence-causes-badimageformatexception/#comments</comments>
		<pubDate>Fri, 23 Apr 2010 10:53:33 +0000</pubDate>
		<dc:creator>ian</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[WinDbg]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[.NET4]]></category>
		<category><![CDATA[CLR]]></category>
		<category><![CDATA[IL]]></category>

		<guid isPermaLink="false">http://www.voyce.com/?p=840</guid>
		<description><![CDATA[Interop assemblies containing certain constructs will cause a BadImageFormatException in .NET 4.0]]></description>
			<content:encoded><![CDATA[<p>I recently discovered a nasty backward compatibility problem with the new type equivalence feature in .NET 4.0. Luckily it&#8217;s relatively difficult to hit it if you&#8217;re in a pure-C# environment, but if you happen to generate any assemblies directly using IL, you should watch out. Read on for all the gory details.<br />
<span id="more-840"></span></p>
<h2>What is .NET type equivalence?</h2>
<p>Described at a high level <a href="http://msdn.microsoft.com/en-us/library/dd997297.aspx">here</a>, .NET 4.0 type equivalence essentially gives you a way of indicating that different .NET types represent the same underlying COM type and is most commonly used in COM interop scenarios. One of the reasons for its introduction is to save developers from having to ship large interop DLLs with their software, e.g. the multi-megabyte Microsoft.Office.Interop. Instead the compiler can inline the definition of any types used, and mark them appropriately as representing the original COM types. </p>
<h2>The error</h2>
<p>We noticed that whenever we built and ran an application that referenced a DLL using .NET 2.0, it worked. Doing the same thing with .NET 4.0 caused a <a href="http://msdn.microsoft.com/en-us/library/system.badimageformatexception.aspx">BadImageFormatException</a>.<br />
<code><br />
Unhandled Exception: System.BadImageFormatException: Could not load file or assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. An attempt was made to load a program with an incorrect format.<br />
   at X.Main()<br />
</code> </p>
<h2>Let&#8217;s dig!</h2>
<p>So, the BadImageFormatException doesn&#8217;t actually tell us much. Let&#8217;s break out WinDbg and see what we can find. Running the faulting app we can see several C++ exceptions before the CLR exception is thrown:<br />
<code><br />
(178c.790): C++ EH exception - code e06d7363 (first chance)<br />
...<br />
(178c.790): C++ EH exception - code e06d7363 (first chance)<br />
(178c.790): CLR exception - code e0434352 (first chance)<br />
</code><br />
I changed the exception handling settings to stop on C++ exceptions (<code>sxe eh</code>) then ran again to see where things were going wrong. It stopped here:<br />
<code><br />
0:000> kp<br />
ChildEBP RetAddr<br />
0012d15c 79084c0f KERNEL32!RaiseException+0x53<br />
0012d194 793371be MSVCR100_CLR0400!_CxxThrowException+0x48<br />
0012d5e4 79455cae clr!EEFileLoadException::Throw+0x1a8<br />
0012d634 794558d2 clr!CompareTypeTokens+0x200<br />
0012d6b0 791b5c00 clr!IsTypeDefEquivalent+0x102<br />
0012d6d4 791b2ca8 <b>clr!MethodTableBuilder::CheckForTypeEquivalence</b>+0x94<br />
0012d7ac 791b27c9 clr!MethodTableBuilder::BuildMethodTableThrowing+0x60d<br />
0012d9a4 791a4578 clr!ClassLoader::CreateTypeHandleForTypeDefThrowing+0x88e<br />
</code><br />
Interesting. Notice how the call stack contains some .NET 4.0 specific methods relating to the new type equivalence feature. We&#8217;re hitting a new code path, which is consistent with the fact that running against a down-level CLR works.</p>
<p>After a bit more toing-and-froing, I discovered that the C++ exception is thrown when <code>clr!MDInternalRO::IsValidToken</code> returns an error. By disassembling the function we can see it&#8217;s just looking at various bits in the token value, and it decides that the value passed (0&#215;02000000) isn&#8217;t valid. Looking at the output from ildasm that token doesn&#8217;t appear anywhere. And if we add a dump of the value, we can see that it indeed doesn&#8217;t look like the other tokens: </p>
<pre>
0:000> bu clr!MDInternalRO::IsValidToken "dd esp+8 L1; g"
...
0012f5a8  02000001
0012f31c  06000001
0012f2c0  02000002
0012f0f4  02000002
0012ebe4  01000001
0012e944  23000001
...
0012d5f4  02000000
(18ec.1ec8): C++ EH exception - code e06d7363 (first chance)
</pre>
<h2>What&#8217;s the culprit?</h2>
<p>So it looks pretty conclusive; the DLL contains something that the CLR isn&#8217;t expecting. But what? It&#8217;s time to break out the oldest tool in the troubleshooting box: the binary chop!</p>
<p>Eventually I got the referenced DLL down to only a single simple construct. Can you guess what it is? A global literal value. A <em>real</em> global value, one that isn&#8217;t even part of a type. Crazy huh? In IL it looks like this:<br />
<code><br />
.field public static literal valuetype Test.MyEnum LiteralValue = int32(0x00000001)<br />
</code><br />
It&#8217;s a literal value of an enumerated type. That&#8217;s important: using a value of a simple type (say int32) does not provoke the error.</p>
<p>Now, I wasn&#8217;t even sure that this is a valid IL construct, but according to the ECMA IL spec, specifically <a href="http://jilc.sourceforge.net/ecma_p2_cil.shtml#_Toc524940530">partition II, section 15</a>, it is:</p>
<blockquote><p>The CLI also supports global fields, which are fields declared outside of any type definition. Global fields shall be static.</p></blockquote>
<p>So it looks like we&#8217;re not doing anything illegal, backed up by the fact that the .NET 2.0 CLR can make use of it without a problem.</p>
<p>Interestingly, there&#8217;s another aspect that influences whether this code path is hit. As mentioned above, type equivalence is intended for use with interop libraries. As such, it only kicks in if your referenced assembly is marked with the PrimaryInteropAssembly attribute, e.g.:</p>
<p><code><br />
  .custom instance void [mscorlib]System.Runtime.InteropServices.PrimaryInteropAssemblyAttribute::.ctor(int32,int32) = ( 01 00 01 00 00 00 00 00 00 00 00 00 )<br />
</code></p>
<h2>The Fix?</h2>
<p>The issue is currently with Microsoft product support. Let&#8217;s see what they come up with; is it too esoteric for a hotfix&#8230;?</p>
<h2>The Repro</h2>
<p>Here&#8217;s some code and instructions on how to repro the problem.</p>
<ol>
<li>Build the IL into a DLL using ilasm.<br />
<code>"c:\WINNT\Microsoft.NET\Framework\v2.0.50727\ilasm.exe" /dll Test.il /output=Test.dll</code>
</li>
<li>Build the application into a .NET 4.0 EXE that references the DLL<br />
<code>"c:\winnt\Microsoft.NET\Framework\v4.0.30319\csc.exe" TestConsumer.cs /reference:Test.dll</code>
</li>
<li>Run the resulting <code>TestConsumer.exe</code> application and you&#8217;ll get the exception</li>
</ol>
<p><b>Test.il</b><br />
<code><br />
.assembly extern mscorlib<br />
{<br />
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )<br />
  .ver 2:0:0:0<br />
}<br />
.assembly Test<br />
{<br />
  .custom instance void [mscorlib]System.Runtime.InteropServices.PrimaryInteropAssemblyAttribute::.ctor(int32,int32) = ( 01 00 01 00 00 00 00 00 00 00 00 00 )<br />
  .hash algorithm 0x00008004<br />
  .ver 1:0:0:0<br />
}<br />
.module Test.dll<br />
.imagebase 0x00400000<br />
.file alignment 0x00000200<br />
.stackreserve 0x00100000<br />
.subsystem 0x0003<br />
.corflags 0x00000001 </p>
<p>.field public static literal valuetype Test.MyEnum LiteralValue = int32(0x00000001)</p>
<p>.class public auto ansi sealed Test.MyEnum<br />
       extends [mscorlib]System.Enum<br />
{<br />
  .field public specialname rtspecialname int32 value__<br />
  .field public static literal valuetype Test.MyEnum Zero = int32(0x00000000)<br />
  .field public static literal valuetype Test.MyEnum One = int32(0x00000001)<br />
}<br />
</code><br />
<b>TestConsumer.cs</b></p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #FF0000;">class</span> X
<span style="color: #000000;">&#123;</span>
    <span style="color: #0600FF;">static</span> <span style="color: #0600FF;">void</span> Main<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
    <span style="color: #000000;">&#123;</span>
        var v <span style="color: #008000;">=</span> Test.<span style="color: #0000FF;">MyEnum</span>.<span style="color: #0000FF;">Zero</span><span style="color: #008000;">;</span>
    <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.voyce.com/index.php/2010/04/23/net-4-0-type-equivalence-causes-badimageformatexception/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Modifying the VC runtime to get better heap allocation stack traces</title>
		<link>http://www.voyce.com/index.php/2010/03/17/modifying-the-vc-runtime-to-get-better-heap-allocation-stack-traces/</link>
		<comments>http://www.voyce.com/index.php/2010/03/17/modifying-the-vc-runtime-to-get-better-heap-allocation-stack-traces/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 23:24:30 +0000</pubDate>
		<dc:creator>ian</dc:creator>
				<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[WinDbg]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[heap]]></category>

		<guid isPermaLink="false">http://www.voyce.com/?p=754</guid>
		<description><![CDATA[Heap allocation stack traces are useless when using certain versions of the MSVC runtime. Is it possible to modify and rebuild MSVCR80 to avoid this?]]></description>
			<content:encoded><![CDATA[<p>Today I was trying to track down some &#8211; how can I put this politely &#8211; &#8220;unusual&#8221; memory usage in some unmanaged code running inside Excel. I broke out WinDbg and tried the usual suspects to get an idea of how memory was being used. Unfortunately, the way that msvcr80.dll is built stopped me from getting decent stack traces for the allocations, so I decided to try and rebuild it with a fix to remedy the situation.<br />
<span id="more-754"></span></p>
<h2>Collecting stack traces</h2>
<p>One of the most helpful things the heap manager can do for you when investigating memory issues is to capture stack traces for each heap allocation. You can enable the &#8220;collect stack traces&#8221; heap flag using the gflags GUI or from within WinDbg:</p>
<pre>
0:006> !gflag +ust
Current NtGlobalFlag contents: 0x00001040
    hpc - Enable heap parameter checking
    ust - Create user mode stack trace database
</pre>
<p>This means that for each heap block (one located at <code>0x0bbf7308</code> in this case), you can see where it was allocated by using the -a (show all information) option:</p>
<pre>
0:006> !heap -p -a 0bbf7308
    address 0bbf7308 found in
    _HEAP @ a630000
      HEAP_ENTRY Size Prev Flags    UserPtr UserSize - state
        0bbf7308 0073 0000  [07]   0bbf7310    00380 - (busy)
        Trace: 401c
        7c96d6dc ntdll!RtlDebugAllocateHeap+0x000000e1
        7c949d18 ntdll!RtlAllocateHeapSlowly+0x00000044
        7c91b298 ntdll!RtlAllocateHeap+0x00000e64
        78134333 MSVCR80!malloc+0x00000077
</pre>
<p>But the obvious problem with this is that the stack trace always stops at malloc. Something&#8217;s allocating some memory? You don&#8217;t say&#8230; </p>
<p>It turns out that this is a <a href="http://http://www.nynaeve.net/?p=209">well understood</a> and documented issue with the Microsoft VC++ runtime, variously known as msvcrt, msvcr70, msvcr71, msvcr80, msvcr90, etc. Unfortunately they&#8217;re all built using the stack frame pointer omission optimisation. Well they&#8217;re built with the <a href="http://msdn.microsoft.com/en-us/library/8f8h5cxt.aspx">-O1</a> (favour small code) option, which implies <a href="http://msdn.microsoft.com/en-us/library/2kxx5t2c.aspx">-Oy</a>. This means that the fast stack-walking algorithm the heap manager uses stops at functions without a return address. The only way to get a decent trace in this situation would be to use the DbgHelp API along with the .pdb files, which would be far too slow to do at each allocation site.</p>
<h2>&#8220;Fixing&#8221; it</h2>
<p>So, given that the source for the runtime library ships as part of Visual Studio, maybe it would be possible to build it without the -Oy option?</p>
<p>My first attempt at building it failed miserably with errors like:<br />
<code><br />
NMAKE : fatal error U1073: don't know how to make 'build\intel\mt_obj\startup.lib'<br />
</code><br />
Luckily this <a href="http://blogs.msdn.com/michkap/articles/478235.aspx">excellent page</a> helped me get past this to a point where I could actually get a DLL built.</p>
<p>The next stage was to modify the build scripts to use different compiler switches. This was simply a case of changing line 69 of <code>makefile.sub</code> from:<br />
<code>CFLAGS=$(CFLAGS) -O1</code><br />
to:<br />
<code>CFLAGS=$(CFLAGS) -O1 <b>-Oy-</b></code></p>
<p>I thought I may have to also modify the build scripts to output a version of the DLL with the same name as the file I was replacing, msvcr80.dll, directly, in case there were internal references to the name in embedded manifests. There&#8217;s a section at the top of the build script for choosing a name for your private version of the library, but it strongly discourages use of the &#8220;reserved&#8221; MSVC* names. Luckily it turns out not to be necessary; the DLL is constructed in such a way as to be rename-able without any ill effects. I could build _sample_.dll (the default output name) and simply copy it to the destination directory in the SxS tree (<code>C:\WINNT\WinSxS\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.3053_x-ww_b80fa8ca</code>) and rename it.</p>
<h2>Result</h2>
<p>Now I get the expected full stack trace (names have been changed to protect the innocent):</p>
<pre>
0:006> !heap -p -a 0bbf7308
    address 0bbf7308 found in
    _HEAP @ a630000
      HEAP_ENTRY Size Prev Flags    UserPtr UserSize - state
        0bbf7308 0073 0000  [07]   0bbf7310    00380 - (busy)
        Trace: 401c
        7c96d6dc ntdll!RtlDebugAllocateHeap+0x000000e1
        7c949d18 ntdll!RtlAllocateHeapSlowly+0x00000044
        7c91b298 ntdll!RtlAllocateHeap+0x00000e64
        78134333 MSVCR80!malloc+0x00000077
        7816207f MSVCR80!operator new+0x0000001d
        fa92336 leakydll!std::allocator<std::vector<ATL::CAdapt<ATL::CComBSTR>,std::allocator<ATL::CAdapt<ATL::CComBSTR> > > >::allocate+0x00000016
        fa9879b leakydll!std::vector<CComVariant,std::allocator<CComVariant> >::resize+0x0000005b
        ...
        ...etc...
</pre>
<p>That&#8217;ll make it <i>much</i> easier to work out what&#8217;s happening and who&#8217;s responsible. Of course, you should be careful with this modified version. Only use it on development machines, and make sure it doesn&#8217;t escape into the wild: with great power comes great responsibility.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.voyce.com/index.php/2010/03/17/modifying-the-vc-runtime-to-get-better-heap-allocation-stack-traces/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Beware of using stack-based COM objects from .NET</title>
		<link>http://www.voyce.com/index.php/2010/01/21/beware-of-using-stack-based-com-objects-from-net/</link>
		<comments>http://www.voyce.com/index.php/2010/01/21/beware-of-using-stack-based-com-objects-from-net/#comments</comments>
		<pubDate>Thu, 21 Jan 2010 17:16:57 +0000</pubDate>
		<dc:creator>ian</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[WinDbg]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[mscorwks]]></category>
		<category><![CDATA[win32]]></category>

		<guid isPermaLink="false">http://www.voyce.com/?p=618</guid>
		<description><![CDATA[COM objects that don't have the expected lifetime can cause chaos when combined with .NETs garbage collection system.]]></description>
			<content:encoded><![CDATA[<p>There are all sorts of nasty things to be aware of if you&#8217;re mixing reference-counted COM objects with garbage-collected .NET. For instance, if you&#8217;re implementing COM objects in C++ then you&#8217;re free to allocate them anywhere you like; on the heap or perhaps on the stack if you know they&#8217;re only used in some specific scope.</p>
<p>But what happens if during the lifetime of that stack based COM object, it gets used from .NET? A runtime callable wrapper (RCW) will be created around the object. And this RCW expects to be able to keep the underlying object alive by incrementing its reference count. Of course, the stack-based object will soon go out of scope, and regardless of its reference count the object will be destroyed and the pointer that the RCW contains will no longer be valid. It points into the stack, so when the RCW gets cleaned-up, the CLR will call via this pointer into memory that contains garbage and you&#8217;ll get something nasty like an access violation or illegal instruction exception. </p>
<p><span id="more-618"></span></p>
<p>It&#8217;s fairly easy to reproduce this to see where things go wrong. It can be useful to see where the CLR blows up, and how we can identify this as the cause.</p>
<p>Lets start by creating a simple pseudo-COM object that implements just the bare minimum to be usable:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">class</span> MyClass <span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> IUnknown
<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
	MyClass<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">:</span>l<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span>
	STDMETHOD_<span style="color: #008000;">&#40;</span>ULONG, AddRef<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000ff;">return</span> InterlockedIncrement<span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>l<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span>
	STDMETHOD_<span style="color: #008000;">&#40;</span>ULONG, Release<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000ff;">return</span> InterlockedDecrement<span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>l<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span>
	STDMETHOD<span style="color: #008000;">&#40;</span>QueryInterface<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span>REFIID iid, <span style="color: #0000ff;">void</span> <span style="color: #000040;">**</span> ppvObject<span style="color: #008000;">&#41;</span>
	<span style="color: #008000;">&#123;</span>
		<span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>iid <span style="color: #000080;">==</span> IID_IUnknown<span style="color: #008000;">&#41;</span>
		<span style="color: #008000;">&#123;</span>
			<span style="color: #000040;">*</span>ppvObject <span style="color: #000080;">=</span> <span style="color: #0000dd;">this</span><span style="color: #008080;">;</span>
			AddRef<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
                        <span style="color: #0000ff;">return</span> S_OK<span style="color: #008080;">;</span>
		<span style="color: #008000;">&#125;</span>
		<span style="color: #0000ff;">return</span> E_NOINTERFACE<span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">private</span><span style="color: #008080;">:</span>
	<span style="color: #0000ff;">long</span> l<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></div></div>

<p>We&#8217;ll also need a COM visible .NET object that will use the object. It doesn&#8217;t actually need to be COM visible, but that&#8217;s the easiest way to access it from C++, in my opinion.</p>
<p>I&#8217;ve created the COM object in F#. It&#8217;s a trivial class that has a single interface, with a single method that takes the object we pass to it and prints its type. This is enough for the RCW to be created.</p>

<div class="wp_syntax"><div class="code"><pre class="fsharp" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">open</span> System
<span style="color: #06c; font-weight: bold;">open</span> System<span style="color: #000080;">.</span><span style="color: #505090;">Runtime</span><span style="color: #000080;">.</span><span style="color: #505090;">InteropServices</span>
&nbsp;
<span style="color: #06c; font-weight: bold;">module</span> Module1 <span style="color: #000080;">=</span>
&nbsp;
    <span style="color: #000080;">&#91;</span><span style="color: #000080;">&lt;</span>ComVisible<span style="color: #000080;">&#40;</span><span style="color: #06c; font-weight: bold;">true</span><span style="color: #000080;">&#41;</span><span style="color: #000080;">;</span> InterfaceType<span style="color: #000080;">&#40;</span>ComInterfaceType<span style="color: #000080;">.</span><span style="color: #505090;">InterfaceIsIUnknown</span><span style="color: #000080;">&#41;</span><span style="color: #000080;">&gt;</span><span style="color: #000080;">&#93;</span>
    <span style="color: #06c; font-weight: bold;">type</span> <span style="color: #06c; font-weight: bold;">public</span> IConsumer <span style="color: #000080;">=</span> 
        <span style="color: #06c; font-weight: bold;">abstract</span> <span style="color: #06c; font-weight: bold;">member</span> UseObject <span style="color: #000080;">:</span> o<span style="color: #000080;">:</span>obj <span style="color: #000080;">-&gt;</span> unit
&nbsp;
    <span style="color: #000080;">&#91;</span><span style="color: #000080;">&lt;</span>ComVisible<span style="color: #000080;">&#40;</span><span style="color: #06c; font-weight: bold;">true</span><span style="color: #000080;">&#41;</span><span style="color: #000080;">;</span> ClassInterface<span style="color: #000080;">&#40;</span>ClassInterfaceType<span style="color: #000080;">.</span><span style="color: #505090;">None</span><span style="color: #000080;">&#41;</span><span style="color: #000080;">&gt;</span><span style="color: #000080;">&#93;</span>
    <span style="color: #06c; font-weight: bold;">type</span> <span style="color: #06c; font-weight: bold;">public</span> Consumer<span style="color: #000080;">&#40;</span><span style="color: #000080;">&#41;</span> <span style="color: #000080;">=</span>
        <span style="color: #06c; font-weight: bold;">interface</span> IConsumer <span style="color: #06c; font-weight: bold;">with</span>
            <span style="color: #06c; font-weight: bold;">member</span> this<span style="color: #000080;">.</span><span style="color: #505090;">UseObject</span> <span style="color: #000080;">&#40;</span>o<span style="color: #000080;">:</span>obj<span style="color: #000080;">&#41;</span> <span style="color: #000080;">=</span>
                Console<span style="color: #000080;">.</span><span style="color: #505090;">WriteLine</span> <span style="color: #000080;">&#40;</span>sprintf <span style="color: #008080;">&quot;%A&quot;</span> <span style="color: #000080;">&#40;</span>o<span style="color: #000080;">.</span><span style="color: #505090;">GetType</span><span style="color: #000080;">&#40;</span><span style="color: #000080;">&#41;</span><span style="color: #000080;">&#41;</span><span style="color: #000080;">&#41;</span></pre></div></div>

<p>We can compile this into a DLL, then run regasm with the /tlb switch to generate a type library (TLB):</p>
<pre>
fsc -o:obj\Debug\testStackObjectsFs.dll Module1.fs
regasm /tlb:testStackObjectsFs.tlb testStackObjectsFs.dll
</pre>
<p>That can be #imported back into our test harness:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#import &quot;testStackObjectsFs.tlb&quot;</span></pre></div></div>

<p>Now we&#8217;re ready to put together some code that creates an instance of our object on the stack and passes it to our .NET component:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">void</span> Foo<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #666666;">// Create an instance of our &quot;COM object&quot; on the stack</span>
	MyClass obj<span style="color: #008080;">;</span>
&nbsp;
	<span style="color: #666666;">// Create a managed object</span>
	testStackObjectsFs<span style="color: #008080;">::</span><span style="color: #007788;">IConsumerPtr</span> mgd<span style="color: #008000;">&#40;</span>__uuidof<span style="color: #008000;">&#40;</span>testStackObjectsFs<span style="color: #008080;">::</span><span style="color: #007788;">Consumer</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
	<span style="color: #666666;">// and pass our COM object to it</span>
	mgd<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>UseObject<span style="color: #008000;">&#40;</span>_variant_t<span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>obj<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">int</span> _tmain<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> argc, _TCHAR<span style="color: #000040;">*</span> argv<span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #666666;">// Initialise the COM runtime, for our purposes it doesn't</span>
	<span style="color: #666666;">// matter which threading model we use</span>
	CoInitializeEx<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">NULL</span>, COINIT_MULTITHREADED<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
	<span style="color: #666666;">// Call a separate function, to ensure stack-based objects</span>
	<span style="color: #666666;">// are out-of-scope on return.</span>
	Foo<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
	<span style="color: #666666;">// Wait for some input</span>
	_getch<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>Now, if you run this from within Visual Studio, if you&#8217;re vigilant (and you haven&#8217;t got your debugger set to stop on access violations), then you&#8217;ll notice this in the output window after the return statement executes:<br />
<code><br />
...<br />
The thread 'Win32 Thread' (0x15b0) has exited with code 11001 (0x2af9).<br />
The thread 'Win32 Thread' (0x1110) has exited with code 0 (0x0).<br />
<b>First-chance exception at 0x00850a2b in testStackObjects.exe: 0xC0000005: Access violation reading location 0x00850a2b.</b><br />
The thread 'DebuggerRCThread::ThreadProcStatic' (0x1534) has exited with code 0 (0x0).<br />
The thread 'RPC Callback Thread' (0x12b8) has exited with code 0 (0x0).<br />
...<br />
</code><br />
Lets ramp up WinDbg, attach to the process (that _getch comes in useful here) and find out what&#8217;s going on in a bit more detail.</p>
<p>If we let the app run to the point of failure in WinDbg, we can see that the CLR was in the act of shutting down when it caused the exception:<br />
<code><br />
0:002> kp<br />
ChildEBP RetAddr<br />
WARNING: Frame IP not in any known module. Following frames may be wrong.<br />
00dae3fc 79f4c1b5 0xe06ff8<br />
00dae450 79f4c26c mscorwks!ReleaseTransitionHelper+0x5f<br />
00dae494 79f4c2d0 mscorwks!SafeReleaseHelper+0x8c<br />
00dae4c8 79faaa01 mscorwks!SafeRelease+0x2f<br />
00dae4fc 79faa7c8 mscorwks!IUnkEntry::Free+0x68<br />
00dae510 79faa91d mscorwks!RCW::ReleaseAllInterfaces+0x18<br />
00dae540 79faa949 mscorwks!RCW::ReleaseAllInterfacesCallBack+0xbd<br />
00dae570 7a0792ac mscorwks!RCW::Cleanup+0x22<br />
00dae57c 7a079714 mscorwks!RCWCleanupList::ReleaseRCWListRaw+0x16<br />
00dae5ac 7a0797df mscorwks!RCWCleanupList::ReleaseRCWListInCorrectCtx+0xdf<br />
00dae5fc 79fdc140 mscorwks!RCWCleanupList::CleanupAllWrappers+0x77<br />
00dafe90 79fdc7aa mscorwks!RCWCache::ReleaseWrappersWorker+0x103<br />
00dafed8 79fd9f95 mscorwks!ReleaseRCWsInCaches+0x27<br />
00dafee0 79f3c76a mscorwks!InnerCoEEShutDownCOM+0x1e<br />
00daff14 79f92015 mscorwks!WKS::GCHeap::FinalizerThreadStart+0x1fc<br />
00daffb4 7c80b683 mscorwks!Thread::intermediateThreadProc+0x49<br />
00daffec 00000000 kernel32!BaseThreadStart+0x37<br />
</code><br />
Essentially it&#8217;s cleaning up the currently unused RCWs &#8211; including our malformed one &#8211; and as part of doing this, it&#8217;s calling Release on the underlying COM object, via the mscorwks!SafeRelease function. SafeRelease wraps the call to potentially (and definitely, in this case) dangerous unmanaged code with various exception handlers, enabling it to silently handle access violations. </p>
<p>If we run the app again, and this time break while it&#8217;s waiting for the keypress, before it attempts to clean up the RCWs, then we can examine the wrapper ourselves, using the approach I set out in <a href="http://www.voyce.com/index.php/2009/09/03/getting-iunknown-from-__comobject/">this post</a>.</p>
<p>List all of the untyped COM object wrappers:</p>
<pre>
0:002> !dumpheap -type System.__ComObject
 Address       MT     Size
<font color="blue"><b>01418628</b></font> 79306e60       16
total 1 objects
Statistics:
      MT    Count    TotalSize Class Name
79306e60        1           16 System.__ComObject
Total 1 objects
</pre>
<p>Use the address of the object to obtain its object header:<br />
<code><br />
0:002> dd <font color="blue">1418628</font>-4 L1<br />
01418624  0800<font color="red"><b>0002</b></font><br />
</code><br />
Use the syncblk identifier in the header to get the syncblk:</p>
<pre>
0:002> !syncblk <font color="red">2</font>
Index SyncBlock MonitorHeld Recursion Owning Thread Info  SyncBlock Owner
    2 <font color="darkgreen"><b>001e4d9c</b></font>            0         0 00000000     none    01418628 System.__ComObject
-----------------------------
Total           2
CCW             0
RCW             0
ComClassFactory 0
Free            0
</pre>
<p>Get the address of the RCW from the sync block:<br />
<code><br />
0:008> dd <font color="darkgreen">001e4d9c</font>+1c L1<br />
001e4db8  001e7dc8<br />
0:008> dd 001e7dc8+c L1<br />
001e7dd4  <font color="purple"><b>001de828</b></font><br />
</code><br />
And dump out the relevant bits of the RCW, the vtable of the object, at offset 0&#215;88, and the IUnknown pointer, at offset 0&#215;64:<br />
<code><br />
0:008> dds <font color="purple">001de828</font>+88 L1<br />
001de8b0  0041ac78 testStackObjects!MyClass::`vftable'<br />
0:008> dds <font color="purple">001de828</font>+64 L1<br />
001de88c  0012fe7c<br />
</code><br />
We can use <code>!address</code> to do a quick sanity check on the pointer and verify what we know to be the case; it&#8217;s stack memory:</p>
<pre>
0:008> !address 0012fe7c
    00030000 : 00124000 - 0000c000
                    Type     00020000 MEM_PRIVATE
                    Protect  00000004 PAGE_READWRITE
                    State    00001000 MEM_COMMIT
                    Usage    <b>RegionUsageStack</b>
                    Pid.Tid  490.13dc
</pre>
<p>If we run the app on again to the point that it fails, we can clearly see the address of the object being passed as an argument to <code>mscorwks!IUnkEntry::Free</code>.</p>
<p>So the moral of the story is; don&#8217;t pretend some arbitrary piece of stack memory is a real, reference counted COM object. You may be saving the cost of a heap allocation, but even if your app works OK today, it may not tomorrow when someone introduces a piece of .NET code somewhere in your object graph.</p>
<h4>Bonus Extra Content</h4>
<p>As a bonus tip, here are a couple of WinDbg breakpoints that can be used to dump each RCW as it&#8217;s created and destroyed.<br />
<code><br />
bu 79faa974 "dds @ecx L23; g"<br />
bu 79faa538 "dd @esp+20 L1; dds poi(@esp+20)+88 L1; g"<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.voyce.com/index.php/2010/01/21/beware-of-using-stack-based-com-objects-from-net/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Getting IUnknown from __ComObject</title>
		<link>http://www.voyce.com/index.php/2009/09/03/getting-iunknown-from-__comobject/</link>
		<comments>http://www.voyce.com/index.php/2009/09/03/getting-iunknown-from-__comobject/#comments</comments>
		<pubDate>Thu, 03 Sep 2009 22:51:35 +0000</pubDate>
		<dc:creator>ian</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[COM]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[WinDbg]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[mscorwks]]></category>
		<category><![CDATA[RCW]]></category>

		<guid isPermaLink="false">http://www.voyce.com/?p=330</guid>
		<description><![CDATA[How do you find the unmanaged COM object that's being referenced by a .NET object?]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m working in an environment with a lot of mixed managed (F#) and unmanaged (C++ COM) code. One of the big problems with this is the mix of lifetime management techniques; .NET uses garbage collection while COM relies on reference counting. Furthermore .NET garbage collection is somewhat non-deterministic, which adds further complexity.</p>
<p>So quite often in our mixed code-base, we find that the .NET garbage collection process doesn&#8217;t kick in when we need it to. For instance, when we&#8217;ve allocated a lot of memory in the COM code that .NET isn&#8217;t aware of. Memory exhaustion has to get pretty bad for the GC to occur at any other time than during a .NET allocation, either the system-wide low-memory event has to be signalled or an <code>OutOfMemoryException</code> needs to be thrown. In both of these cases it&#8217;s probably too late to do anything about it.</p>
<p>In this case it&#8217;s extremely useful to be able to see what .NET objects are still alive, and what COM objects they&#8217;re hanging on to. Unfortunately this isn&#8217;t as easy as it might seem.<br />
<span id="more-330"></span><br />
The COM object itself hides within a weakly-typed <code>System.__ComObject</code> or a strongly-typed managed wrapper, depending on whether rich type information is available. Furthermore, a runtime controller RCW (runtime callable wrapper) is what actually holds a pointer to the object itself, and this structure is internal to mscorwks.dll.</p>
<p>So how can we untangle this and, on finding a <code>__ComObject</code> that happens to still be alive (i.e. is not reachable in the object graph and is therefore eligible for garbage collection) identify which COM object it&#8217;s hanging on to.</p>
<p>First of all, let&#8217;s see how many <code>__ComObjects</code> are still alive. In this case, it&#8217;s only one (phew!):</p>
<pre>
0:005> !DumpHeap -type __ComObject
 Address       MT     Size
01453b74 79306e60       16
total 1 objects
Statistics:
      MT    Count    TotalSize Class Name
79306e60        1           16 System.__ComObject
Total 1 objects
</pre>
<p>And you remember the layout of .NET objects in memory, don&#8217;t you? Of course you do! The 4 bytes prior to the address displayed (<code>01453b74</code>) are the &#8220;object header&#8221;. The exact content of the header is apparently undocumented. Let&#8217;s see what it contains (at least on a 32-bit platform, your mileage may vary):</p>
<pre>
0:005> dd 01453b74-4 L1
01453b70  08000002
</pre>
<p>According to various sources the object header contains 2 fields; a handle and a sync block index. If the object is an RCW, the handle is always 0&#215;08000. You can use the index with SOS&#8217;s <code>!syncblk</code> command to de-reference it:</p>
<pre>
0:005> !syncblk 2
Index SyncBlock MonitorHeld Recursion Owning Thread Info  SyncBlock Owner
    2 001e0fec            0         0 00000000     none    01453b74 System.__ComObject
-----------------------------
Total           3
CCW             0
RCW             1
ComClassFactory 0
Free            0
</pre>
<p>The sync block itself is an undocumented structure, but after a bit of investigation, it turns out that at offset 0&#215;1c there is a pointer to a further structure that contains the &#8220;interop information&#8221;:</p>
<pre>
0:005> dd 001e0fec+1c L1
001e1008  001e9510
</pre>
<p>And from this, we can obtain a pointer to the RCW itself. We&#8217;re almost there!</p>
<pre>
0:005> dd 001e9510+c L1
001e951c  001e5380
</pre>
<p>The RCW is a pretty large structure, but for our purposes there are only a couple of interesting fields: the IUnknown pointer at 0&#215;64, and the object&#8217;s virtual function table pointer at 0&#215;88. If you use <code>dds</code> you can easily see any symbols associated with these pointers:</p>
<pre>
0:005> dds 01e5380+64 L1
001e53e4  00ef6c24
</pre>
<pre>
0:005> dds 01e5380+88 L1
001e5408  00eb9710 rcwrepro!ATL::CComObject<ctestObject>::`vftable'
</pre>
<p>This is the salient information; we now know exactly what type of COM object we&#8217;re dealing with. This is obviously a bit fragile, given that it relies on structures from mscorwks that may well change in newer versions of the runtime (I&#8217;ll check on .NET 4 when I get a chance). It&#8217;s also a bit of a pain to go through all these steps manually in WinDbg, so I put together a simple extension DLL to do it automatically given the address of the __ComObject. I&#8217;ll upload that and blog about it soon.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.voyce.com/index.php/2009/09/03/getting-iunknown-from-__comobject/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Finding the largest free block of address space</title>
		<link>http://www.voyce.com/index.php/2009/08/21/largest-free-block-of-address-space/</link>
		<comments>http://www.voyce.com/index.php/2009/08/21/largest-free-block-of-address-space/#comments</comments>
		<pubDate>Fri, 21 Aug 2009 20:57:12 +0000</pubDate>
		<dc:creator>ian</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[WinDbg]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[address space]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[perfmon]]></category>
		<category><![CDATA[private bytes]]></category>
		<category><![CDATA[win32]]></category>

		<guid isPermaLink="false">http://www.voyce.com/?p=258</guid>
		<description><![CDATA[I&#8217;ve been seeing problems recently with fragmented virtual address space. During the lifetime of a process, bits and pieces of memory are allocated throughout the 2GB 32-bit address space to such an extent that large contiguous blocks of free space are no longer available. If anything subsequently requires a large block of memory (like, for [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://72.47.193.211/wp-content/uploads/2009/08/buildings_small.png"><img src="http://72.47.193.211/wp-content/uploads/2009/08/buildings_small.png" alt="Buildings" title="Buildings" width="100" height="100" class="alignleft size-full wp-image-268" /></a>I&#8217;ve been seeing problems recently with fragmented virtual address space. During the lifetime of a process, bits and pieces of memory are allocated throughout the 2GB 32-bit address space to such an extent that large contiguous blocks of free space are no longer available. If anything subsequently requires a large block of memory (like, for instance, a somewhat out-of-date version of the GHC runtime), it will fail to get it.</p>
<p>It&#8217;s obvious looking at the output from <a href="http://www.voyce.com/index.php/2009/07/28/diagnosing-out-of-memory-errors-with-vmmap/">VMmap</a> or windbg&#8217;s <code>!address</code> command what the largest contiguous block is, e.g.</p>
<pre>
0:008> !address -summary
....
Largest free region: Base 07300000 - Size 63ed0000 (1637184 KB)
</pre>
<p>But what if you need that number in order to make a decision at run-time? For instance, to decide whether your process is in a fit state to continue, or if it should instead commit <a href="http://en.wikipedia.org/wiki/Seppuku">hara-kiri</a>. In that case, you need to access the information programmatically. That&#8217;s where the immensely useful <a href="http://msdn.microsoft.com/en-us/library/aa366907(VS.85).aspx">VirtualQueryEx</a> function comes in&#8230;<br />
<span id="more-258"></span><br />
VirtualQueryEx gives you information on a single page of your virtual address space at a time. Pages size are dependent on the architecture and OS, but if you just want to iterate over all of them, you don&#8217;t need to add any special handling; the function returns the size of the page in an element of the <a href="http://msdn.microsoft.com/en-us/library/aa366775(VS.85).aspx">MEMORY_BASIC_INFORMATION</a> structure, so you can simply move to the &#8216;next&#8217; page regardless of size.</p>
<p>If you&#8217;re interested in free space, you&#8217;ll need to find all the pages that have a state of MEM_FREE (0&#215;10000), and that&#8217;s pretty much all there is to it. By keeping track of how much space falls into a continuous range of MEM_FREE pages you can get to the number reported by VMmap and <code>!address</code>.</p>
<p>Here&#8217;s some C++ code that returns the address of the largest free contiguous block in <code>largestFreestart</code and the size in <code>largestFree</code>. Enjoy!</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">	MEMORY_BASIC_INFORMATION mbi<span style="color: #008080;">;</span>
	DWORD start <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">bool</span> recording <span style="color: #000080;">=</span> <span style="color: #0000ff;">false</span><span style="color: #008080;">;</span>
	DWORD freestart <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span>, largestFreestart <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
	__int64 <span style="color: #0000dd;">free</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span>, largestFree <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">true</span><span style="color: #008000;">&#41;</span>
	<span style="color: #008000;">&#123;</span>
		SIZE_T s <span style="color: #000080;">=</span> VirtualQueryEx<span style="color: #008000;">&#40;</span>hproc, <span style="color: #0000ff;">reinterpret_cast</span><span style="color: #000080;">&lt;</span>lpvoid<span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span>start<span style="color: #008000;">&#41;</span>, <span style="color: #000040;">&amp;</span>mbi, <span style="color: #0000dd;">sizeof</span><span style="color: #008000;">&#40;</span>mbi<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
		<span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>s <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #0000dd;">sizeof</span><span style="color: #008000;">&#40;</span>mbi<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
		<span style="color: #008000;">&#123;</span>
			<span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>GetLastError<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">!</span><span style="color: #000080;">=</span> ERROR_INVALID_PARAMETER<span style="color: #008000;">&#41;</span>
				<span style="color: #0000ff;">return</span> ReportError<span style="color: #008000;">&#40;</span>GetLastError<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, _T<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;Failed to VirtualQueryEx at %08x&quot;</span><span style="color: #008000;">&#41;</span>, start<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
			<span style="color: #0000ff;">else</span>
				<span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
		<span style="color: #008000;">&#125;</span>
		<span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>mbi.<span style="color: #007788;">State</span> <span style="color: #000080;">==</span> MEM_FREE<span style="color: #008000;">&#41;</span>
		<span style="color: #008000;">&#123;</span>
			<span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>recording<span style="color: #008000;">&#41;</span>
				freestart <span style="color: #000080;">=</span> start<span style="color: #008080;">;</span>
			<span style="color: #0000dd;">free</span> <span style="color: #000040;">+</span><span style="color: #000080;">=</span> mbi.<span style="color: #007788;">RegionSize</span><span style="color: #008080;">;</span>
			recording <span style="color: #000080;">=</span> <span style="color: #0000ff;">true</span><span style="color: #008080;">;</span>
		<span style="color: #008000;">&#125;</span>
		<span style="color: #0000ff;">else</span>
		<span style="color: #008000;">&#123;</span>
			<span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>recording<span style="color: #008000;">&#41;</span>
			<span style="color: #008000;">&#123;</span>
				<span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #0000dd;">free</span> <span style="color: #000080;">&gt;</span> largestFree<span style="color: #008000;">&#41;</span>
				<span style="color: #008000;">&#123;</span>
					largestFree <span style="color: #000080;">=</span> <span style="color: #0000dd;">free</span><span style="color: #008080;">;</span>
					largestFreestart <span style="color: #000080;">=</span> freestart<span style="color: #008080;">;</span>
				<span style="color: #008000;">&#125;</span>
			<span style="color: #008000;">&#125;</span>
			<span style="color: #0000dd;">free</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
			recording <span style="color: #000080;">=</span> <span style="color: #0000ff;">false</span><span style="color: #008080;">;</span>
		<span style="color: #008000;">&#125;</span>
		start <span style="color: #000040;">+</span><span style="color: #000080;">=</span> mbi.<span style="color: #007788;">RegionSize</span><span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.voyce.com/index.php/2009/08/21/largest-free-block-of-address-space/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Diagnosing out of memory errors with VMMap</title>
		<link>http://www.voyce.com/index.php/2009/07/28/diagnosing-out-of-memory-errors-with-vmmap/</link>
		<comments>http://www.voyce.com/index.php/2009/07/28/diagnosing-out-of-memory-errors-with-vmmap/#comments</comments>
		<pubDate>Tue, 28 Jul 2009 22:38:19 +0000</pubDate>
		<dc:creator>ian</dc:creator>
				<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[WinDbg]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[memory]]></category>
		<category><![CDATA[private bytes]]></category>
		<category><![CDATA[VMMap]]></category>
		<category><![CDATA[win32]]></category>

		<guid isPermaLink="false">http://www.voyce.com/?p=216</guid>
		<description><![CDATA[VMMap is a new tool from Mark Russinovich et al that's very useful for diagnosing virtual memory/address space exhaustion issues. I describe it here, and give some information that should help you interpret what it reports.]]></description>
			<content:encoded><![CDATA[<p>The other day a colleague pointed me to a new tool from Mark Russinovich et al (ex-SysInternals) that turns out to be very useful for diagnosing virtual memory/address space exhaustion issues. I thought I&#8217;d describe it here, and give some &#8211; hopefully useful &#8211; extra information on what it reports.</p>
<p>(I had problems with WordPress choking on this long post, so I&#8217;ve split it into 2 parts. This the first part, the second part is <a href="http://www.voyce.com/index.php/2009/07/29/diagnosing-out-of-memory-errors-with-vmmap-part-2/">here</a>).</p>
<p><span id="more-216"></span><br />
First things first: you can download it from <a href="http://technet.microsoft.com/en-us/sysinternals/dd535533.aspx">here</a>.</p>
<h2>Using VMMap</h2>
<p>VMMap graphically displays the contents of your processes&#8217; virtual memory, which each type of memory colour coded. This means you can quickly get an idea of how all of your valuable 2GB address space is being used.</p>
<p>At this point it&#8217;s worth pointing out that this article refers to the 32 bit Windows XP platform only, as that&#8217;s what I use on a day-to-day basis. Moving to a 64 bit address space makes it so large that exhaustion of a process&#8217; address space is pretty damn unlikely, discounting your application doing something pathological.</p>
<p><div id="attachment_219" class="wp-caption alignleft" style="width: 310px"><a href="http://72.47.193.211/wp-content/uploads/2009/07/overview.png"><img src="http://www.voyce.com/wp-content/uploads/2009/07/overview-300x99.png" alt="VMMap top pane" title="VMMap top pane" width="300" height="99" class="size-medium wp-image-219" /></a><p class="wp-caption-text">VMMap top pane</p></div> Before digging in to the different types of allocation, you can quickly get a good overview using the top part of the window.<br clear="all"/>The top bar, Virtual Memory Summary (5040K in this example), corresponds to the Committed memory column and the Working Set summary bar (1140K) below it corresponds to the Total WS column.</p>
<p>The number in the bottom left in the largest free block of address space. It&#8217;s the same number as reported by <code>!address -summary</code> in WinDbg. See the post <a href="http://www.voyce.com/index.php/2009/08/21/largest-free-block-of-address-space/">here</a> if you want to calculate it programmatically. If this number is small (less than 64MB) you&#8217;ll probably have out of memory issues, see below for more details.</p>
<p><b>Note:</b> Generally the working set size is NOT the important number here; it&#8217;s a common mistake that people make when looking at memory usage figures in something like Task Manager. The working set size is merely an indication of the amount of virtual memory that has recently been accessed and it&#8217;s entirely possible to make the WS size number plummet by explicitly &#8220;flushing&#8221; the working set. You can do this by, for example, minimising a GUI application. As such, this is really not the number you want to be tracking. Instead, look at the Private Bytes or Virtual Memory Size counter in perfmon.</p>
<p>But back to VMMap. There are various different types of allocation reported. I&#8217;ll describe some of the most interesting ones:</p>
<h3>Image</h3>
<p>A DLL or other executable file, as typically loaded by <code>LoadLibraryEx</code>. You&#8217;ll see the protection is Execute/Copy on Write; this is the standard for executables, where the OS will share the memory between processes unless they modify it &#8211; which is very rare.</p>
<p>You may also see the same file loaded as a mapped image. For instance, when using a COM server that contains an embedded type library resource, it will be loaded in both ways; once as an executable using <code>LoadLibrary</code> and once as a mapped file using <code>LoadTypeLib</code>. You may also notice that non-ngen&#8217;d .NET images are mapped <b>twice</b>. This appears to be a bug that Microsoft are aware of, there&#8217;s a <a href="http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=467560">bug</a> logged in Connect for it.</p>
<p>You can expand the image entry to see the size of the image sections, the file header, code (.text), resources (.rsrc) and relocations (.reloc) for example.</p>
<h3>Mapped file</h3>
<p>These are typically data files loaded using <code>CreateFileMapping</code>. Depending on how the mapping was created (whether an explicit maximum size was specified), either the whole of the file or some small section of it will be mapped. Of course, the whole point of memory mapped files is to be able to get access to sections of a file without having to load it all, so the chances are that only small files will be mapped in their entirety.</p>
<p>Memory mapped files are often used to share data between processes, so you may find that things put on the clipboard may appear as mapped address space, albeit transiently. This is especially obvious in Microsoft Office apps like Excel.</p>
<h3>Heaps</h3>
<p>This is the meta-data associated with each heap in the process. The actual allocations from the heap are stored separately in the address space (more on that later, see Private Data).</p>
<p>Some people are surprised that there can be multiple heaps in a single process, but it&#8217;s actually quite common practice in unmanaged code, especially where there are specific memory management requirements. MSXML is a widely used example of this; it does it&#8217;s own garbage collection using it&#8217;s own dedicated heaps.</p>
<p>There is always a default heap created by the loader during process creation, and others are created explicitly using <code>HeapCreate</code>. The address of the heap displayed by VMMap can be used with the WinDbg <code>!heap</code> command to delve more deeply into it&#8217;s contents and structure. For instance, <code>!heap -m</code> will display it&#8217;s segment details.</p>
<h3>Managed heap</h3>
<p>Obviously this is only relevant for applications using .NET &#8211; managed apps themselves or unmanaged apps that implicitly load .NET assemblies in some other way, say, via COM. The number displayed is the sum of the generation 0, 1, 2 and large object heap sizes.</p>
<h3>Thread stack</h3>
<p>Each thread in the OS has a stack that can grow to 1MB by default (although this is configurable at link time, and controllable programmatically). It starts as a block of uncommitted reserved memory, with the used space committed at the bottom, and a guard block that is used to determine when to expand the block downwards. VMMap helpfully displays the thread ID in the stack space row.</p>
<p>Remember that each thread will have it&#8217;s own stack space, so spinning up threads is not free in terms of virtual memory use. See <a href="http://msdn.microsoft.com/en-us/library/ms686774(VS.85).aspx">here</a> for more details on thread stack space.</p>
<p>Read on <a href="http://www.voyce.com/index.php/2009/07/29/diagnosing-out-of-memory-errors-with-vmmap-part-2/">here</a> for more&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.voyce.com/index.php/2009/07/28/diagnosing-out-of-memory-errors-with-vmmap/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>WinDbg !locks command broken</title>
		<link>http://www.voyce.com/index.php/2009/06/03/windbg-locks-command-broken/</link>
		<comments>http://www.voyce.com/index.php/2009/06/03/windbg-locks-command-broken/#comments</comments>
		<pubDate>Wed, 03 Jun 2009 09:23:37 +0000</pubDate>
		<dc:creator>ian</dc:creator>
				<category><![CDATA[Debugging]]></category>
		<category><![CDATA[WinDbg]]></category>

		<guid isPermaLink="false">http://www.voyce.com/?p=163</guid>
		<description><![CDATA[It seems that the extremely useful !locks command is broken in 6.11.1.40x, the current and previous release of WinDbg from the debugging tools for Windows.
You&#8217;ll get errors like:

0:007> !locks
NTSDEXTS: Unable to resolve ntdll!RTL_CRITICAL_SECTION_DEBUG type
NTSDEXTS: Please check your symbols

The suggested solution seems to be to roll-back to version 6.10.3.233, available from here, or you can just [...]]]></description>
			<content:encoded><![CDATA[<p>It seems that the <em>extremely</em> useful <code>!locks</code> command is broken in 6.11.1.40x, the current and previous release of WinDbg from the <a href="http://www.microsoft.com/whdc/DevTools/Debugging/default.mspx">debugging tools for Windows</a>.</p>
<p>You&#8217;ll get errors like:</p>
<pre>
0:007> !locks
NTSDEXTS: Unable to resolve ntdll!RTL_CRITICAL_SECTION_DEBUG type
NTSDEXTS: Please check your symbols
</pre>
<p>The suggested solution seems to be to roll-back to version 6.10.3.233, available from <a href="http://msdl.microsoft.com/download/symbols/debuggers/dbg_x86_6.10.3.233.msi">here</a>, or you can just replace the version of <code>ntsdexts.dll</code> in the <code>c:\program files\debugging tools for windows (x86)\winxp</code> directory with the one from the earlier release.</p>
<p>Judging by the error message, I&#8217;m guessing that the new version may work if you happen to be using a debug (checked) build of the Windows kernel, but I don&#8217;t have one around to try it with.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.voyce.com/index.php/2009/06/03/windbg-locks-command-broken/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Troubleshooting an InvalidProgramException</title>
		<link>http://www.voyce.com/index.php/2008/10/01/troubleshooting-an-invalidprogramexception/</link>
		<comments>http://www.voyce.com/index.php/2008/10/01/troubleshooting-an-invalidprogramexception/#comments</comments>
		<pubDate>Wed, 01 Oct 2008 18:58:53 +0000</pubDate>
		<dc:creator>ian</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[WinDbg]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[.local]]></category>
		<category><![CDATA[dll]]></category>
		<category><![CDATA[gac]]></category>
		<category><![CDATA[InvalidProgramException]]></category>
		<category><![CDATA[mscoree]]></category>
		<category><![CDATA[mscorjit]]></category>
		<category><![CDATA[mscorwks]]></category>

		<guid isPermaLink="false">http://www.voyce.com/?p=45</guid>
		<description><![CDATA[One of the developers who uses the .NET/COM interop DLL that I wrote recently informed me that when they used it in a certain way, they would get a fatal System.InvalidProgramException. Nasty. So I set about seeing how I could find out exactly why this was happening: here are the gory details&#8230;
To spoil the ending [...]]]></description>
			<content:encoded><![CDATA[<p>One of the developers who uses the .NET/COM interop DLL that I wrote recently informed me that when they used it in a certain way, they would get a fatal System.InvalidProgramException. Nasty. So I set about seeing how I could find out exactly why this was happening: here are the gory details&#8230;</p>
<p>To spoil the ending somewhat, we already knew the precise situation that was causing the problem. This is different to the average issue, where most of the time&#8217;s spent in isolating the conditions that cause it. In this case we had an excellent positive and negative repro case.</p>
<p>The users were attempting to use the legacy .local approach to changing DLL probing. This was originally implemented around the time of Windows 2000, before the current side-by-side system existed, and basically short-circuited the normal DLL search order to inject the current directory as the first potential location. See the <a href="http://msdn.microsoft.com/en-us/library/ms682600%28VS.85%29.aspx">DLL redirection</a> MSDN page for more information.</p>
<p>There was already a version of the assembly in question installed in the GAC, they just wanted to use the .local file to override it. The trouble was, with certain builds of the DLL (we&#8217;ll call it XYZ.dll) in the directory along with the redirection file (appname.exe.local), an fatal InvalidProgramException would be generated by the .NET execution engine. With other builds of the same DLL it worked. Mysterious.</p>
<p>So the first thing to do was to try and find out exactly where the exception was occurring. I ramped up WinDbg, and took a look at what exceptions were being thrown:<br />
<code><br />
(42c.1e90): CLR notification exception - code e0444143 (first chance)<br />
(42c.1e90): Unknown exception - code 02345678 (first chance)<br />
(42c.1e90): C++ EH exception - code e06d7363 (first chance)<br />
(42c.1e90): C++ EH exception - code e06d7363 (first chance)<br />
(42c.1e90): C++ EH exception - code e06d7363 (first chance)<br />
(42c.1e90): CLR exception - code e0434f4d (first chance)<br />
</code><br />
The last one generated a second chance exception and the exit. I changed the exception filter set to stop on .NET notifications &#8211; which are generated when assemblies are loaded &#8211; and for C++ exceptions:<br />
<code><br />
0:000&gt; sxe clrn<br />
0:000&gt; sxe eh<br />
</code><br />
After restarting and running on from the CLR notification (generated whenever an assembly is loaded) I got a stack trace on the C++ exception that was being generated within the CLR:<br />
<code><br />
0:000&gt; kP<br />
ChildEBP RetAddr<br />
0012eea4 78158e89 KERNEL32!RaiseException+0x53<br />
0012eedc 79fce58e MSVCR80!_CxxThrowException+0x46<br />
0012ef0c 7a015309 mscorwks!RealCOMPlusThrow+0xd8<br />
0012f2ac 79f0e795 mscorwks!UnsafeJitFunction+0x365<br />
0012f350 79e87f52 mscorwks!MethodDesc::MakeJitWorker+0x1c1<br />
0012f3a8 79e8809e mscorwks!MethodDesc::DoPrestub+0x486<br />
0012f3f8 00341f3e mscorwks!PreStubWorker+0xeb<br />
</code><br />
Hmmmm, interesting, so it looks like the JIT compiler is failing. I also noticed that there was a strange exception that I didn&#8217;t recognise:<br />
<code><br />
(42c.1e90): Unknown exception - code 02345678 (first chance)<br />
</code><br />
You&#8217;ve got to love those &#8220;made up&#8221; numbers. I added an exception filter for it and restarted again (good job this failure was quick to manifest).<code><br />
</code><br />
Now I got an even more precise fault location:<br />
<code><br />
0:000&gt; kP<br />
ChildEBP RetAddr<br />
0012ec44 790af56c KERNEL32!RaiseException+0x53<br />
0012ec60 7909deea mscorjit!getJit+0x38<br />
0012ec7c 79066362 mscorjit!Compiler::fgFindJumpTargets+0x33d<br />
0012ece0 790614c6 mscorjit!Compiler::fgFindBasicBlocks+0x4d<br />
0012ed20 79061236 mscorjit!Compiler::compCompile+0x2bf<br />
0012edb4 7906118c mscorjit!jitNativeCode+0xb8<br />
0012edec 79f0f9cf mscorjit!CILJit::compileMethod+0x3d<br />
0012ee58 79f0f945 mscorwks!invokeCompileMethodHelper+0x72<br />
0012ee9c 79f0f8da mscorwks!invokeCompileMethod+0x31<br />
0012eef4 79f0ea33 mscorwks!CallCompileMethodWithSEHWrapper+0x84<br />
0012f2ac 79f0e795 mscorwks!UnsafeJitFunction+0x230<br />
0012f350 79e87f52 mscorwks!MethodDesc::MakeJitWorker+0x1c1<br />
0012f3a8 79e8809e mscorwks!MethodDesc::DoPrestub+0x486<br />
0012f3f8 00341f3e mscorwks!PreStubWorker+0xeb<br />
</code><br />
So now its looking like something&#8217;s going wrong deep down in the JITter. After stepping through the disassembly for a while I decided to have a look at precisely what method was being compiled at this point. You can use the DumpMD command from the sos extension to examine the method, which is the first parameter to UnsafeJitFunction (you can see parameters in the stack trace by using kb):<br />
<code><br />
0:000&gt; !DumpMD 0161ad08<br />
Method Name: XXX()<br />
Class: 01670a40<br />
MethodTable: 0161ad18<br />
mdToken: 0601626b<br />
Module: 00d3323c<br />
IsJitted: no<br />
m_CodeOrIL: ffffffff<br />
</code><br />
Now this is suspicious; the method as listed (XXX &#8211; name changed to protect the innocent) isn&#8217;t what we were expecting. In fact, it&#8217;s completely different. Let&#8217;s see what IL is being JITted:<br />
<code><br />
0:000&gt; !DumpIL 161ad08<br />
error decoding IL<br />
</code><br />
OK, so this is completely broken metadata.</p>
<p>Now, given that we were using the .local, we would have expected to see the DLL being loaded from the same directory as the application, so lets take a look and see what we&#8217;ve got loaded:<br />
<code><br />
0:000&gt; !DumpDomain<br />
--------------------------------------<br />
System Domain: 7a3bc8b8<br />
...snip...<br />
Assembly: 001abe28 [C:\WINNT\assembly\GAC_MSIL\XYZ.DLL]<br />
ClassLoader: 001aa0b0<br />
SecurityDescriptor: 001aa018<br />
Module Name<br />
00d3323c C:\WINNT\assembly\GAC_MSIL\XYZ.DLL<br />
</code><br />
So this looks like the culprit; we&#8217;re still loading the version from the GAC, even though there&#8217;s a .local file present. Just to verify this I set a breakpoint on CreateFileW to show me which DLLs were being loaded and by what:<br />
<code><br />
0:000&gt; bu KERNEL32!CreateFileW "dpu (@esp+4) L1"<br />
</code><br />
This tells the debugger to display the unicode string that is the first parameter to CreateFileW whenever it&#8217;s hit.<br />
There are obviously lots of DLLs loaded, even in this simple case, but eventually it led me to the point where the GAC version was being loaded:<br />
<code><br />
0012cf44 001ac5a0 "C:\WINNT\assembly\GAC_MSIL\XYZ.dll"<br />
eax=00000000 ebx=00000001 ecx=79e7f683 edx=7c90eb94 esi=001ac4e0 edi=7c80ac0f<br />
eip=7c810760 esp=0012cf40 ebp=0012cf64 iopl=0 nv up ei pl nz na po nc<br />
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202<br />
KERNEL32!CreateFileW:<br />
7c810760 8bff mov edi,edi</code></p>
<p><code>0:000&gt; kp L30<br />
ChildEBP RetAddr<br />
0012cf3c 79e90f12 KERNEL32!CreateFileW<br />
0012cf64 79f29306 mscorwks!WszCreateFile+0x72<br />
0012cfac 79ed27ac mscorwks!PEImage::GetFileHandle+0x60<br />
0012cfdc 79e981ae mscorwks!PEImage::GetLayoutInternal+0xcf<br />
0012d020 79e98e69 mscorwks!PEImage::GetLayout+0x8a<br />
0012d0bc 79e98934 mscorwks!RuntimeOpenImageInternal+0x103<br />
0012d104 79e988a9 mscorwks!GetAssemblyMDInternalImportEx+0x9d<br />
0012d11c 79ec314d mscorwks!CreateMetaDataImport+0x16<br />
0012d13c 79ec30ee mscorwks!CAssemblyManifestImport::Init+0x35<br />
0012d164 79ed39ca mscorwks!CreateAssemblyManifestImport+0x53<br />
0012d180 79ed3943 mscorwks!CreateAssemblyFromManifestFile+0x48<br />
0012d3e8 79ed380f mscorwks!CheckExistsInGAC+0x179<br />
0012d418 79ed320a mscorwks!CreateAssemblyFromCacheLookup+0x9b<br />
...snip...</code></p>
<p>So then I waited until the exception was fired, and used !dlls to show me what other DLLs were loaded:<br />
<code><br />
0:000&gt; !dlls<br />
...<br />
0x00243a68: C:\Temp\interopx\XYZ.dll<br />
Base 0x036a0000 EntryPoint 0x00000000 Size 0x0095c000<br />
Flags 0x90404000 LoadCount 0x00000001 TlsIndex 0x00000000<br />
LDRP_ENTRY_PROCESSED<br />
LDRP_COR_IMAGE<br />
...<br />
</code><br />
Ouch. We&#8217;ve loaded some metadata from the c:\winnt\assembly\GAC_MSIL\XYZ.dll version, and then we&#8217;ve actually loaded the c:\temp\interopx\XYZ.dll module. It turned out that in some cases the metadata matched, and we got away with it, and at other times (for different builds) it didn&#8217;t and we hit the InvalidProgramException.</p>
<p>So, the moral of the story is, don&#8217;t mix .local and the .NET assembly loader. And if you do, prepare to break out your WinDbg skills.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.voyce.com/index.php/2008/10/01/troubleshooting-an-invalidprogramexception/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating a featherweight debugger</title>
		<link>http://www.voyce.com/index.php/2008/06/11/creating-a-featherweight-debugger/</link>
		<comments>http://www.voyce.com/index.php/2008/06/11/creating-a-featherweight-debugger/#comments</comments>
		<pubDate>Wed, 11 Jun 2008 08:20:46 +0000</pubDate>
		<dc:creator>ian</dc:creator>
				<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[WinDbg]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://www.voyce.com/?p=29</guid>
		<description><![CDATA[What do I mean by &#8220;featherweight debugger&#8221;? I mean implementing just enough of the debugging framework to get what we need from the debuggee and nothing more.
The problem I was trying to solve was how to get more information from first chance exceptions. We have a great deal of library code that uses catch(&#8230;) blocks [...]]]></description>
			<content:encoded><![CDATA[<p>What do I mean by &#8220;featherweight debugger&#8221;? I mean implementing just enough of the debugging framework to get what we need from the debuggee and nothing more.</p>
<p>The problem I was trying to solve was how to get more information from first chance exceptions. We have a great deal of library code that uses catch(&#8230;) blocks to prevent any exceptions &#8211; even structured ones like access violations &#8211; from escaping into the application. This is pretty important when your code is running inside an Excel session that someone may&#8217;ve been working on for hours (and which could take minutes just to re-calculate in the event of having to re-open it). Unfortunately, because the catch handlers are built into all the code, if you discover something causing access violations, say, there&#8217;s no single place that you can change to get more diagnostic information.</p>
<p>So, with source level changes ruled out, how else could you catch exceptions?</p>
<p>Well, the obvious thing that does this already is the debugger, so I decided to look at the <a href="http://msdn.microsoft.com/en-us/library/ms679300(VS.85).aspx">debugging API</a>, and see if it was possible to use that. It turns out that the implementation is pretty simple; essentially the debugger simply waits on an event in a loop, receiving further specific information about the event when it&#8217;s fired.</p>
<div style="font-family: Lucida Sans Typewriter; font-size: 10pt; color: black; background: white;">
<p style="margin: 0px;">    DEBUG_EVENT DebugEv;                   <span style="color: #008000;">// debugging event information </span></p>
<p style="margin: 0px;">    DWORD dwContinueStatus = DBG_CONTINUE; <span style="color: #008000;">// exception continuation </span></p>
<p style="margin: 0px;">    <span style="color: #0000ff;">while</span> (<span style="color: #0000ff;">true</span>)</p>
<p style="margin: 0px;">    {</p>
<p style="margin: 0px;">        WaitForDebugEvent(&amp;DebugEv, INFINITE);</p>
<p style="margin: 0px;"> </p>
<p style="margin: 0px;">        <span style="color: #0000ff;">switch</span> (DebugEv.dwDebugEventCode)</p>
<p style="margin: 0px;">        {</p>
<p style="margin: 0px;">            <span style="color: #008000;">// Do something with event</span></p>
<p style="margin: 0px;">            <span style="color: #008000;">// Set dwContinueStatus to tell debuggee what to do </span></p>
<p style="margin: 0px;">        }</p>
<p style="margin: 0px;"> </p>
<p style="margin: 0px;">        <span style="color: #008000;">// Resume executing the thread that reported the debugging event. </span></p>
<p style="margin: 0px;">        ContinueDebugEvent(DebugEv.dwProcessId,</p>
<p style="margin: 0px;">                           DebugEv.dwThreadId,</p>
<p style="margin: 0px;">                           dwContinueStatus);</p>
<p style="margin: 0px;">    }</p>
</div>
<p>There are several &#8216;informational&#8217; events, DLLs being loaded and unloaded etc, and, more interestingly, there&#8217;s one called <span style="font-size: x-small; font-family: Lucida Sans Typewriter;">EXCEPTION_ACCESS_VIOLATION</span>. Voila!</p>
<p>When this event is received, we can use the additional information we&#8217;re passed, along with some thread context data, to create a minidump. This is an extremely useful mechanism for snapshotting the process in a rich enough way to provide full post-mortem debugging abilities.</p>
<p>Here&#8217;s some sample code to create a minidump using the with enough information to be able to (amongst other things):</p>
<ul>
<li>Get stack traces</li>
<li>Get memory usage information (using !address -summary)</li>
</ul>
<div style="font-family: Lucida Sans Typewriter; font-size: 10pt; color: black; background: white;">
<p style="margin: 0px;">DWORD CreateMiniDump(DEBUG_EVENT ev)</p>
<p style="margin: 0px;">{</p>
<p style="margin: 0px;">    HANDLE hproc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ev.dwProcessId);</p>
<p style="margin: 0px;">    <span style="color: #0000ff;">if</span> (!hproc)</p>
<p style="margin: 0px;">        <span style="color: #0000ff;">return</span> ReportError(_T(<span style="color: #800000;">&#8220;Failed to open process&#8221;</span>),GetLastError());</p>
<p style="margin: 0px;"> </p>
<p style="margin: 0px;">    EXCEPTION_POINTERS ep;</p>
<p style="margin: 0px;">    ep.ExceptionRecord = &amp;ev.u.Exception.ExceptionRecord;</p>
<p style="margin: 0px;">    HANDLE hthread = OpenThread(THREAD_ALL_ACCESS, FALSE, ev.dwThreadId);</p>
<p style="margin: 0px;">    <span style="color: #0000ff;">if</span> (!hthread)</p>
<p style="margin: 0px;">    {</p>
<p style="margin: 0px;">        DWORD dw = GetLastError();</p>
<p style="margin: 0px;">        CloseHandle(hproc);</p>
<p style="margin: 0px;">        <span style="color: #0000ff;">return</span> ReportError(_T(<span style="color: #800000;">&#8220;Failed to open thread&#8221;</span>),dw);</p>
<p style="margin: 0px;">    }</p>
<p style="margin: 0px;">    CONTEXT ctxt;</p>
<p style="margin: 0px;">    ZeroMemory(&amp;ctxt, sizeof(ctxt));</p>
<p style="margin: 0px;">    GetThreadContext(hthread, &amp;ctxt);</p>
<p style="margin: 0px;">    ep.ContextRecord = &amp;ctxt;</p>
<p style="margin: 0px;"> </p>
<p style="margin: 0px;">    TCHAR sz[MAX_PATH];</p>
<p style="margin: 0px;">    _stprintf_s(sz, _countof(sz), _T(<span style="color: #800000;">&#8220;c:\\dump_%ld_%ld_%ld.dmp&#8221;</span>), ev.dwProcessId, ev.dwThreadId, nDumps++);</p>
<p style="margin: 0px;">    HANDLE hfile = CreateFile(sz, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL);</p>
<p style="margin: 0px;">    <span style="color: #0000ff;">if</span> (!hfile)</p>
<p style="margin: 0px;">    {</p>
<p style="margin: 0px;">        DWORD dw = GetLastError();</p>
<p style="margin: 0px;">        CloseHandle(hproc);</p>
<p style="margin: 0px;">        <span style="color: #0000ff;">return</span> ReportError(_T(<span style="color: #800000;">&#8220;Failed to create output file&#8221;</span>),dw);</p>
<p style="margin: 0px;">    }</p>
<p style="margin: 0px;"> </p>
<p style="margin: 0px;">    MINIDUMP_EXCEPTION_INFORMATION info;</p>
<p style="margin: 0px;">    info.ClientPointers = FALSE;</p>
<p style="margin: 0px;">    info.ThreadId = ev.dwThreadId;</p>
<p style="margin: 0px;">    info.ExceptionPointers = &amp;ep;</p>
<p style="margin: 0px;">    <span style="color: #0000ff;">if</span> (!MiniDumpWriteDump(hproc, ev.dwProcessId, hfile,</p>
<p style="margin: 0px;">        MiniDumpWithFullMemory,</p>
<p style="margin: 0px;">        &amp;info,</p>
<p style="margin: 0px;">        NULL,</p>
<p style="margin: 0px;">        NULL))</p>
<p style="margin: 0px;">    {</p>
<p style="margin: 0px;">        DWORD dw = GetLastError();</p>
<p style="margin: 0px;">        CloseHandle(hfile);</p>
<p style="margin: 0px;">        CloseHandle(hproc);</p>
<p style="margin: 0px;">        <span style="color: #0000ff;">return</span> ReportError(_T(<span style="color: #800000;">&#8220;Failed to write mini dump&#8221;</span>),dw);</p>
<p style="margin: 0px;">    }</p>
<p style="margin: 0px;">    CloseHandle(hfile);</p>
<p style="margin: 0px;">    CloseHandle(hproc);</p>
<p style="margin: 0px;">    _tprintf(_T(<span style="color: #800000;">&#8221; Minidump written to %s\n&#8221;</span>), sz);</p>
<p style="margin: 0px;">    <span style="color: #0000ff;">return</span> ERROR_SUCCESS;</p>
<p style="margin: 0px;">}</p>
</div>
<p>Caveat: Example code only, please excuse the hard-coded path!</p>
<p>The debugger loop is then wrapped up as a stand-alone application that can be passed the PID of a process to debug. Assuming we&#8217;ve got sufficient permissions, our debugger can attach to that process using <span style="font-size: 10pt; background: white; color: #000000; font-family: Lucida Sans Typewriter;">DebugActiveProcess(pid)</span>.</p>
<p>So, here we have a relatively lightweight way of &#8216;watching&#8217; another process and grabbing lots of potentially useful diagnostic information in the event that something untoward happens. Of course when using this in the wild you&#8217;d also need some means of tidying up the generated files, and potentially some means of logging that the event had occurred, but these are relatively straightforward to implement.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.voyce.com/index.php/2008/06/11/creating-a-featherweight-debugger/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

