如何使用Reflection.Emit调试在运行时生成的IL代码

时间:2008-11-26 15:57:14

标签: c# .net vb.net

我试图在运行时使用Reflection.Emit命名空间中的DynamicMethod类生成一些代码但由于某种原因它抛出了“VerificationException”。这是我试图使用的IL代码......

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

我需要一种方法来调试生成的IL代码。我有什么选择?我正在使用VS2008专业版。

6 个答案:

答案 0 :(得分:9)

我在这里找到了更多帮助...

DebuggerVisualizer for DynamicMethod (Show me the IL) 这是一个调试器可视化工具,使用它可以在运行时看到生成的IL!

更好的是Debugging LCG,它允许您在运行时使用Windbg调试生成的代码!

答案 1 :(得分:2)

尝试使用peverify工具检查IL。来自MSDN:

  

peverify.exe执行全面   MSIL验证检查基于   数据流分析加上一个列表   数百条有效的规则   元数据。有关的详细信息   Peverify.exe执行的检查,请参阅   “元数据验证   规范“和”MSIL   指令集规范“   工具开发人员指南中的文件夹   .NET Framework SDK。

您需要将生成的代码保存到磁盘中作为程序集,这样才有用。

答案 2 :(得分:0)

在使用调试器(至少不是内置)的意义上,无法直接调试IL。你真的只有两个选择

  1. 问Rob建议。手动将IL和ilasm输入到DLL / EXE中。然后在生成的DLL上运行peverify以查看错误。
  2. 如果你真的想调试IL那么你可能会坚持做原始组装。

答案 3 :(得分:0)

您需要发出符号信息才能调试IL。

Emitting Symbolic Information with Reflection Emit

并将发出的操作码与发出它的文件中的相应位置相匹配。(ILGenerator.Emit()调用的地方)。

但这当然不是一项微不足道的任务。

编辑:

你无法调试那些不可验证的代码,它根本就没有Jit-ed。您需要检查IL操作的正确用法。堆栈中是否包含了所需类型的正确操作数?

编辑2:

简单的方法是使用C#创建代码,然后使用Reflector或其他IL反汇编程序,也可以查看IL并将其与您的IL进行比较。

编辑3:不幸的是,无法使用DynamicMethod发出调试信息,但可以使用WinDBG来转储IL,Jose Fco Bonnin在他的博客中解释了这一点。 Executing dynamic IL with DynamicMethod:

  

我们遇到的主要问题   DynamicMethod是我们没有的   能够生成调试信息   对于LCG,因为调试API是   基于LCG所做的元数据   没有。无论如何,并非所有人都失去了   因为我们可以继续调试   WinDBG的。 ...

该过程在帖子中进一步解释。

答案 4 :(得分:0)

这可能对调试结束没有帮助,但RunSharp是一个很好的生成IL的工具,可以帮助您避免常见的陷阱。它使写作IL感觉更像是编写C#。

以下是示例概述:http://www.codeproject.com/KB/dotnet/runsharp.aspx

答案 5 :(得分:0)

ldarg.1
ldarg.0
ldfld, System.String FirstName
callvirt, Void Write(System.String)

在这个阶段你仍然有堆栈上的arg1。