Friday, August 29, 2008 3:05 AM bart

To Bind or Not To Bind – Dynamic Expression Trees – Intermezzo: SOS in Visual Studio

Last time we talked about dealing with dynamic code generation using Reflection.Emit to generate calls to our dynamic binder. I’ve shown how to see the IL that gets generated by means of the Dynamic IL Visualizer add-in in Visual Studio. In this post I want to point out that you can actually live without that visualizer and go the hard-core way using SOS, aka “Son of Strike”, the WinDbg extension for managed code debugging that ships with the .NET Framework (sos.dll). A little-known fact is that SOS can be loaded directly in Visual Studio through the Immediate Window.

Note: This post is screenshot-driven; to conserve bandwidth I’ve included only thumbnails in the post itself; “click to enlarge” is the message.

Note: There are many ways to get to the information you care about; in the end we’re dealing with object graphs. This post is more an exploration of the data that you can get at if you want to do so; the various paths to get there are more a matter of style (in physical terms: the potential energy is constant, but the accumulated kinetic energy corresponding to the developer’s finger muscle contractions when dealing with the keyboard may vary).

 

Step 1 – Loading SOS

We’re on a breakpoint in managed code and will try to load SOS through the Immediate Window using .load sos:

image

For this to work, native code debugging needs to be enabled in the project properties:

image

 

Step 2 – Finding dynamic methods

To find the dynamically generated methods, we can search the heap for objects of type DynamicMethod using .dumpheap DynamicMethod. As you can see we don’t have any yet:

image

Using F10 we step to the next method, executing Compile causing the dynamic method for the expression to be compiled. Rerunning the command now yields:

image

We’re in business. As you can see we had two matching types: DynamicMethod and DynamicMethod+RTDynamicMethod. We’re interested in the former one, so we follow the MT field back to the list of objects. MT stands for Method Table which is a runtime structure describing the object layout for a particular type. It can be used to locate fields and methods in preparation to calls. If you want, you can use !dumpmt –MD <MT address> to dump such a table; this will show all of the “methods in the table”.

 

Step 3 – Dumping the IL

Now that we have the DynamicMethod object, we can dump the IL for it using !dumpIL <object address>:

image

As we were compiling the identity function I, the IL shown should just be a ldarg.0 and sure it is.

 

Step 4 – Another sample

We could have stopped with the previous sample but our dynamic dispatch is interesting to analyze too. Breaking after our Substring sample compilation (in a fresh run, so that the old DynamicMethod is no longer displayed) results in:

image

We can follow it through to the IL again:

image

Notice the call to “something in parentheses”. This is the runtime token representing the method, which we can dump using !do <address>. In addition, !dumpIL hints at dumping the token array:

image

The result of doing so is an array of tokens used in the IL stream. I’ll show this in a second but you might wonder what those fancy numbers in the IL stream like “70000002” stand for. Those indicate token types as defined in CorTokenType (see corhdr.h, for instance in the SSCLI “Rotor” distribution). To find the token type, mask with 0xFF000000, so in our sample that leaves 0x70000000 and this is defined as mdtString. The remainder (mask with 0x00FFFFFF) leaves us with the RID (relative ID) of 0x00000002, so entry two in the table contains the corresponding token value:

image

And yes, we see “Substring” appearing. Similarly value 2000003 in IL_0010 gives us a type def token (for System.Object) at offset 3 and value 0a000004 in IL_0031 gives us a member ref token (for our DynamicBinder.Call method) at offset 4. For the latter one, the debugger output gives you the indirection in between parentheses straight away:

image

How convenient!

 

Step 5 - From token to MethodInfo to DeclaringType

Next we can follow the object chains all the way up to the declaring type: first we get from the token to the method it represents and second we can traverse m_declaringType to get the corresponding type:

image

This produces a System.RuntimeType instance containing a Method Table reference:

image

So we can dump the method table with !dumpmt –MD <MT address> as follows:

image

As you can see we’re in our DynamicBinder class.

 

Step 6 – What about the signature?

Instead of following the path to the m_declaringType above, we could follow the m_signature as well:

image

System.Signature wraps a m_signature field of type SignatureStruct which we can dump as well, but as this is a value type we can’t use !do but rather need to use !dumpvc (standing for value class) passing in the method table (otherwise the debugger wouldn’t know how to interpret the struct which is simply a blob of data) and the address.

 

Step 7 – And back to the method being called

From the signature struct we can reach out to the method represented by the signature through m_pMethod. This is a runtime handle, wrapping an IntPtr pointer to where the loaded IL code lives. In other words, we can invoke dumpIL on that address to see the contents of what turns out to be our DynamicBinder.Call method:

image

(Notice the closure classes in the IL generated because of our C# 3.0 lambda expressions embedded in the LINQ query we use for method overload resolution.)

 

Step 8 – Dynamic modules

Dynamic methods live in dynamic modules, so it would be interesting to see those. SOS comes to the rescue with !dumpdomain.

image

Scroll down a bit and we get to see the dynamic modules. With some poking around it turns out that the last one is the one we’re looking for as it contains a multicast delegate, precisely what we've been generating. We can visualize it using !dumpmodule –mt <address> also showing the types that are referenced inside the module (that’s where we see the MulticastDelegate).

image

Also notice the attribute saying “Reflection”. To see how the type definition (TypeDef) is indirected through a method table map (MethodTableMap), follow the arrows below. Green indicates the indexing and again the masked first two bytes of the green value indicate the CorTokenType, in this case a TypeDef. You can do the same exercise for the TypeRef (0x01000000) – follow the memory pointer and get the first (zero-based count obviously) element referred in there (it should read 24 e5 0f 79 as you can infer from the output produced by the debugger, considering little endian conversion).

image

Unfortunately the defined type is marked as unloaded so we’re at a dead end – feel free to explore the Method Table for the type a bit further. In a similar way you can track down the loaded module with our DynamicBinder to do some explorations (also starting from !dumpdomain):

image

Dumping the binder’s method table gives us:

image

Who still needs ILDASM or Reflector? :-)

 

Step 9 – Walking the stack

To finish this post, I’d like to show how to dump the stack objects using !dso to get to some of this information through yet an alternative route:

image

In green I’ve indicated the result of the dynamic call and what it corresponds to. However, the items in red indicate our (mysterious?) unloaded type once more. As you’ll see though, the IL is still available:

image

The result is predictable by now I guess.

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Filed under: ,

Comments

# re: To Bind or Not To Bind – Dynamic Expression Trees – Intermezzo: SOS in Visual Studio

Friday, August 29, 2008 5:24 AM by Oren Novotny

There's an easier way to see the IL for dynamic methods -- or really anything with a MethodInfo or a DynamicMethod -- a debug visualizer. I'm not sure who wrote it, but it's referenced here: http://weblogs.asp.net/rosherove/archive/2007/11/02/debugger-visualizers-for-methodinfo-dynamicmethod-and-methodbase.aspx I've tried it and it's pretty slick...

# Dew Drop - August 29, 2008 | Alvin Ashcraft's Morning Dew

Pingback from  Dew Drop - August 29, 2008 | Alvin Ashcraft's Morning Dew

# re: To Bind or Not To Bind – Dynamic Expression Trees – Intermezzo: SOS in Visual Studio

Friday, August 29, 2008 11:23 AM by bart

Hi Oren,

Exactly - that's why a have a sentence saying "I’ve shown how to see the IL that gets generated by means of the Dynamic IL Visualizer add-in in Visual Studio." and a link to such a thing in my first post on the topic. Roy's is another one that can be used too.

Thanks,

-Bart

# re: To Bind or Not To Bind – Dynamic Expression Trees – Intermezzo: SOS in Visual Studio

Friday, August 29, 2008 4:16 PM by Oren Novotny

Ah, I was more focused on the rest of the article :)

# Reflective Perspective - Chris Alcock &raquo; The Morning Brew #170

Tuesday, September 02, 2008 12:19 AM by Reflective Perspective - Chris Alcock » The Morning Brew #170

Pingback from  Reflective Perspective - Chris Alcock  &raquo; The Morning Brew #170

# Recent Faves Tagged With "blob" : MyNetFaves

Wednesday, April 08, 2009 8:35 PM by Recent Faves Tagged With "blob" : MyNetFaves

Pingback from  Recent Faves Tagged With "blob" : MyNetFaves

# Recent Links Tagged With "route" - JabberTags

Thursday, April 30, 2009 2:49 PM by Recent Links Tagged With "route" - JabberTags

Pingback from  Recent Links Tagged With "route" - JabberTags