views:

164

answers:

2

Hello everyone,

I am using Windbg to diassemble managed code (written in C#, console application) using Windbg's !U command from sos.dll. I find when using !U to diassemble a managed function, the diassembled IL code only contains function calls I made, and for remaining parts (non-function call C# code), for example a=a*2, and foreach loops in C#, only native assembly language code is shown, is that the correct expected behavior?

My quesition is, I want to know whether !U is capable of diassemble managed code binary DLL into IL with all code (besides function call code)?

thanks in advance, George

+1  A: 

I don't think WinDbg works at the IL level. You'd probably have to use ildasm to get an IL disassembly.

Chris Jester-Young
I know ildasm or reflector could do that. But I am debugging in runtime or debugging in crash dump, and I need call stack address information along with IL code (which ildasm or reflector cannot provide). If only native assembly code is shown, it is hard to debug, and it is why I want to diassemble to IL code with call stack address information. Any comments or solutions?
George2
+3  A: 

If you want to dump IL while debugging you can use the !dumpil command from SOS. It takes a MethodDesc pointer as input, so you have to obtain that first.

One way to get the MethodDesc pointer use the !name2ee command.

So for instance if you have a method Foo in the type Bar (in assembly ClassLibrary1) use !name2ee like this

0:000> !name2ee ClassLibrary1!ClassLibrary1.Bar.Foo
Module: 001630bc (ClassLibrary1.dll)
Token: 0x06000001
MethodDesc: 00163450  <=== HERE
Name: ClassLibrary1.Bar.Foo()
JITTED Code Address: 007500f0

Following that, you can do a !dumpil 00163450 to dump the IL for method Foo like this

0:000> !dumpil 00163450
ilAddr = 73532050
IL_0000: ldstr "Foo"
IL_0005: call System.Console::WriteLine
Brian Rasmussen
I find !dumpil cannot dump native address information? For example, if I find my code crashes or breaks at native address 0x11111111, I want to see which IL code it is executing? Could !dumpil do that?
George2
You have to remember, that IL code doesn't actually run. It is compiled to native code which is then run. However, if you do a dump of a crashing process you'll have both the JITTED code and the original IL available as part of the dump. Use !U to show CLR aware disassemly of generated code. Use !dumpil to show IL. From the exception stack trace and the !name2ee you should be able to locate both the JITTED and the IL code as needed.
Brian Rasmussen
My problem is, using !U willl never should IL code for non-function call managed code, for non-function call managed code (e.g. a=a+2 or foreach loop), only native assembly code is showed. Is that expected behavior?
George2
!U disassembles the JIT compiled code and unlike its native counterpart, u it is CLR aware, so it can map some of the internal calls to things that make sense to a developer in the managed world. However, it is still a disassembly of the native code. High level constructs like foreach looks very different when compiled because the instructions in a high level language like C# needs many operations to implement in machine code. Let me turn this around a bit and ask: what are you trying to accomplish?
Brian Rasmussen