Viewing Emitted IL using SOS Debugging Extension

Look at the MSIL and the native machine code for methods generated through Reflrction.Emit.

1,Now let us look at the stack.Execute the command "!clrstack".You'll get the stack pointer and instruction pointer for each frame.The result should look something like this:

!clrstack
OS Thread Id: 0x10e0 (4320)
Child SP IP       Call Site
0012f3ac 031b01c1 ConsoleApplication1.Program.Main(System.String[])
0012f648 791421bb [GCFrame: 0012f648]
执行命令期间出现错误: IDebugClient 请求了未实现的接口

2,The second-from-top entry looks intriguing.How can we see its code?The first thing we need to do is to get a method descriptor for it,which we can do using the SOS command !ip2md.

!ip2md 031b01c1
MethodDesc:   00a13800
Method Name:  ConsoleApplication1.Program.Main(System.String[])
Class:        00a1147c
MethodTable:  00a1382c
mdToken:      7314b7a806000005
Module:       00a12e9c
IsJitted:     yes
CodeAddr:     031b0070
Transparency: Critical
执行命令期间出现错误: IDebugClient 请求了未实现的接口

With the method descriptor,the !dumpil command will show us the actual MSIL for this method.

!dumpil 00a13800
ilAddr = 00402050
IL_0000: nop
IL_0001: ldsfld System.String::Empty
IL_0006: ldtoken System.Int32
IL_000b: call System.Type::GetTypeFromHandle
IL_0010: ldnull
IL_0011: ldtoken ConsoleApplication1.Program
IL_0016: call System.Type::GetTypeFromHandle
IL_001b: callvirt System.Type::get_Module
IL_0020: newobj System.Reflection.Emit.DynamicMethod::.ctor
IL_0025: stloc.0
IL_0026: ldloc.0
IL_0027: callvirt System.Reflection.Emit.DynamicMethod::GetILGenerator
IL_002c: stloc.1
IL_002d: ldloc.1
IL_002e: ldsfld System.Reflection.Emit.OpCodes::Call
IL_0033: ldloc.0
IL_0034: ldnull
IL_0035: callvirt System.Reflection.Emit.ILGenerator::EmitCall
IL_003a: nop
IL_003b: ldloc.1
IL_003c: ldsfld System.Reflection.Emit.OpCodes::Pop
IL_0041: callvirt System.Reflection.Emit.ILGenerator::Emit
IL_0046: nop
IL_0047: ldloc.1
IL_0048: ldsfld System.Reflection.Emit.OpCodes::Ret
IL_004d: callvirt System.Reflection.Emit.ILGenerator::Emit
IL_0052: nop
IL_0053: call System.Console::Read
IL_0058: pop
IL_0059: ret

If you want to see what the associated x86 or x64 machine code looks like,the "CodeAddr" value from the !ip2md command will give you the starting address of the JITted code.You can use this with the windbg "u" command (for "unassemble").

注意:

clrstack命令可以用来获得一个托管代码调用栈.

ClrStack命令输出的第一部分信息是所显示线程的ID.这是底层操作系统的线程ID.接下来,它显示了托管调用栈的所有栈桢,这时,我们可以更清楚的看到那些函数被调用了.

OS Thread Id: 0x10e0 (4320)
Child SP IP       Call Site
0012f3ac 031b01c1 ConsoleApplication1.Program.Main(System.String[])
0012f648 791421bb [GCFrame: 0012f648]
执行命令期间出现错误: IDebugClient 请求了未实现的接口

首先,Main函数被调用,接下来是调用[GCFrame: 0012f648] ,这个调用将被转换为一组栈桢.每个栈侦还给出了该栈桢所需的参数类型.

posted @ 2012-04-17 22:08  szjdw  阅读(439)  评论(0编辑  收藏  举报