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

时间:2022-02-27 19:05:58

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...

我试图在运行时使用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

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

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

6 个解决方案

#1


9  

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!

DynamicMethod的DebuggerVisualizer(向我展示IL)它是一个调试器可视化工具,使用它可以在运行时看到生成的IL!

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

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

#2


2  

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

尝试使用peverify工具检查IL。来自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.

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

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

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

#3


0  

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

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

  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. 问Rob建议。手动将IL和ilasm输入到DLL / EXE中。然后在生成的DLL上运行peverify以查看错误。
  3. If you are actually wanting to debug the IL then you're likely stuck with doing it raw assembly.
  4. 如果你真的想调试IL那么你可能会坚持做原始组装。

#4


0  

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#.

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

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

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

#5


0  

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

您需要发出符号信息才能调试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).

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

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?

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

Edit 2:

编辑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.

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

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:

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

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. ...

我们使用DynamicMethod遇到的主要问题是我们无法为LCG生成调试信息,因为调试API基于LCG没有的元数据。在任何情况下,由于我们可以继续使用WinDBG进行调试,因此并非全部丢失。 ...

the process is explained further in the post.

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

#6


0  

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

At this stage you still have arg1 on the stack.

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

#1


9  

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!

DynamicMethod的DebuggerVisualizer(向我展示IL)它是一个调试器可视化工具,使用它可以在运行时看到生成的IL!

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

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

#2


2  

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

尝试使用peverify工具检查IL。来自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.

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

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

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

#3


0  

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

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

  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. 问Rob建议。手动将IL和ilasm输入到DLL / EXE中。然后在生成的DLL上运行peverify以查看错误。
  3. If you are actually wanting to debug the IL then you're likely stuck with doing it raw assembly.
  4. 如果你真的想调试IL那么你可能会坚持做原始组装。

#4


0  

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#.

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

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

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

#5


0  

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

您需要发出符号信息才能调试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).

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

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?

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

Edit 2:

编辑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.

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

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:

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

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. ...

我们使用DynamicMethod遇到的主要问题是我们无法为LCG生成调试信息,因为调试API基于LCG没有的元数据。在任何情况下,由于我们可以继续使用WinDBG进行调试,因此并非全部丢失。 ...

the process is explained further in the post.

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

#6


0  

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

At this stage you still have arg1 on the stack.

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