Note that there are some explanatory texts on larger screens.

plurals
  1. POReading instance fields when debugging JIT'ed assemblies
    text
    copied!<p>Over the last couple of weeks, I've been playing around with <a href="http://msdn.microsoft.com/en-us/library/ms404520.aspx" rel="noreferrer">the unmanaged .NET debugging API</a>.</p> <p>While MSDN documents the interfaces itself, to find out how to actually use them in any meaningful way, I resorted to various blogs (mainly <a href="http://blogs.msdn.com/b/jmstall/" rel="noreferrer">Mike Stall's</a>) and the managed wrappers in <a href="http://www.microsoft.com/en-us/download/details.aspx?id=2282" rel="noreferrer">the CLR Managed Debugger samples</a> and the <a href="https://github.com/icsharpcode" rel="noreferrer">ILSpy sources</a>. In the end I was able to attach my test program to a running process, set breakpoints and hit them.</p> <p>What I would like to do next is on hitting such a breakpoint, read a field of the relevant object instance. This works fine when the debug target method hasn't been NGEN'ed or JIT'ed, by <a href="http://www.reflector.net/2012/03/debugging-debugging-experience/" rel="noreferrer">disabling loading NGEN'ed assemblies</a> (the environment setting 'COMPLUS_ZAPDISABLE=1') and <a href="http://msdn.microsoft.com/en-us/library/9dd8z24x.aspx" rel="noreferrer">disabling JIT optimizations</a> (aka the '.ini file trick'). </p> <p>However, when I try the same with my ideal target - retail optimized (NGEN/JIT'ed) code - it doesn't work. For instance: I can on hitting the entry breakpoint still retrieve the number of method arguments, but I can't get the first argument itself (debugging API throws an exception).</p> <p>Now, I imagine the reason for this is because the debugging APIs are supposed to be platform independent, and in this case the assemblies aren't anymore. But what if I accept this platform dependency to an Intel one: as far as I'm aware the CLR uses the <a href="http://en.wikipedia.org/wiki/X86_calling_conventions" rel="noreferrer">fastcall calling convention</a> where in this case the ECX register contains the first method argument (the implicit 'this' reference for member functions).</p> <p>I tested this, and indeed on hitting the breakpoint, ECX contains the OBJECTREF (address of the object instance), in NGEN'ed assemblies.</p> <p>Now the final step in reading the instance field is to retrieve the field offset relative to this pointer, and this is where I'm stuck, since I seem unable to find out how the CLR does <a href="http://msdn.microsoft.com/en-us/magazine/cc163791.aspx" rel="noreferrer">the packing of the instance fields during native code generation</a>.</p> <p>I realize this may be CLR version/implementation dependent, but apparently there are ways, as WinDbg with the SOS extension is able to find this layout. If not through the debugging APIs, could I somehow leverage SOS.dll ?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload