tags:

views:

1216

answers:

6

Hi,

I am trying to generate some code at runtime using the DynamicMethod class in the Reflection.Emit namespace but for some reason its throwing a "VerificationException". Here is the IL code I am trying to use...

ldarg.1
ldarg.0
ldfld, System.String FirstName
callvirt, Void Write(System.String)
ldarg.1
ldarg.0
ldfld, System.String LastName
callvirt, Void Write(System.String)
ldarg.1
ldarg.0
ldfld, Int32 Age
callvirt, Void Write(Int32)
ret

I need a way to debug the generated IL code. What options do I have? I am using VS2008 professional.

Regards,
Sandeep Datta.

+2  A: 

Try using the peverify tool to check the IL. From MSDN:

peverify.exe performs comprehensive MSIL verification checks based on dataflow analysis plus a list of several hundred rules on valid metadata. For detailed information on the checks Peverify.exe performs, see the "Metadata Validation Specification" and the "MSIL Instruction Set Specification" in the Tools Developers Guide folder in the .NET Framework SDK.

You'll need to save the generated code to disk as an assembly for this to be useful though.

Rob Walker
A: 

There is no way to debug IL directly in the sense of using a debugger (not builtin at least). You really only have two options here

  1. Ask Rob suggested. Manually type out the IL and ilasm into a DLL/EXE. Then run peverify on the resulting DLL to see your error.
  2. If you are actually wanting to debug the IL then you're likely stuck with doing it raw assembly.
JaredPar
A: 

You need to emit symbolic information in order to be able to debug the IL.

Emitting Symbolic Information with Reflection Emit

and match the emitted opcodes with the coresponding location in your file that emits it.(Where ILGenerator.Emit() call is).

But this is certainly not a trivial task.

Edit:

you can't debug code that is not verifiable, it doesn't get Jit-ed at all. You need to check your correct usage of IL ops. does every of have in the stack the proper operands of the required type which it expects?

Edit 2:

And easy way to do it is to create the code using C# then use Reflector or some other IL disassembler too see the IL and compare it to yours.

Edit 3: Unfortunately debug info can't be emitted using DynamicMethod, but WinDBG can be used to dump the IL, Jose Fco Bonnin explains it in his blog. Executing dynamic IL with DynamicMethod:

The main problem we experience with DynamicMethod is that we do not have the ability to generate debugging info for LCG, since the debugging API is based on metadata that the LCG does not have. In any case, not all is lost since we can continue debugging with WinDBG. ...

the process is explained further in the post.

Pop Catalin
Can I use Symbolic information with dynamic methods (LCG)? I have checked my IL against reflector and they are identical. But I am not sure if the generated IL is **actually** indentical.
SDX2000
I've made an edit to answer your question, hope it helps.
Pop Catalin
A: 

This may not help you at the debugging end, but RunSharp is a nice tool for generating IL that helps you avoid common pitfalls. It makes Writing IL feel a lot more like writing C#.

Here is an overview with examples: http://www.codeproject.com/KB/dotnet/runsharp.aspx

Neil Whitaker
I have tried RunSharp and I must say I was impressed but finally I settled on doing it the hard way since it seems to have been abandoned. For example you cannot check the return value of a method call (Invoke has no mechanism to return the return value)!
SDX2000
A: 
ldarg.1
ldarg.0
ldfld, System.String FirstName
callvirt, Void Write(System.String)

At this stage you still have arg1 on the stack.

leppie
Yes, which is used as an argument to the call to BinaryWriter::Write. Its a reference to a BinaryWriter Object and is passed in as the "this pointer".
SDX2000
Right :) Missed that!
leppie
+4  A: 

Hi All,

I have found some more help here...

DebuggerVisualizer for DynamicMethod (Show me the IL) It's is a debugger visualizer using which you will be able to see the generated IL at runtime!

And even better is Debugging LCG which allows you to debug the generated code at runtime using Windbg!

SDX2000