Compiler construction 使CLR/.NET语言可调试

Compiler construction 使CLR/.NET语言可调试,compiler-construction,dynamic,debugging,cil,dynamic-language-runtime,Compiler Construction,Dynamic,Debugging,Cil,Dynamic Language Runtime,使CLR/.NET语言可调试的资源有哪些?我正在开发一个ActionScript3到IL编译器,它使用DLR调用站点和调用站点绑定器来处理静态编程语言的动态方面。我正在寻找有关将发出的IL映射回源代码的任何信息,我还想知道如何将动态调用站点映射回源代码 所以这最终是两个问题: 如何使IL可调试 如何使DLR呼叫站点可调试 任何帮助都将不胜感激 我想要的是“调试能力” 在附加的Visual Studio实例中: 单步执行代码 查看本地人 查看堆栈跟踪 要使IL可调试,需要将代码编译成可调试程

使CLR/.NET语言可调试的资源有哪些?我正在开发一个ActionScript3到IL编译器,它使用DLR调用站点和调用站点绑定器来处理静态编程语言的动态方面。我正在寻找有关将发出的IL映射回源代码的任何信息,我还想知道如何将动态调用站点映射回源代码

所以这最终是两个问题:

  • 如何使IL可调试
  • 如何使DLR呼叫站点可调试
任何帮助都将不胜感激

我想要的是“调试能力” 在附加的Visual Studio实例中:

  • 单步执行代码
  • 查看本地人
  • 查看堆栈跟踪

要使IL可调试,需要将代码编译成可调试程序集。还有一个直接的缺点是GC无法收集程序集。要执行此操作,请执行
AppDomain.CurrentDomain.DefinedDynamicAssembly
,然后调用
DefinedDynamicModule
并在程序集中定义一个模块。要使其可调试,需要在其上设置一些属性:

DebuggableAttribute.DebuggingModes attrs =
    DebuggableAttribute.DebuggingModes.Default |
    DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints |
    DebuggableAttribute.DebuggingModes.DisableOptimizations;

Type[] argTypes = new Type[] { typeof(DebuggableAttribute.DebuggingModes) };
Object[] argValues = new Object[] { attrs };

_myAssembly.SetCustomAttribute(new CustomAttributeBuilder(
   typeof(DebuggableAttribute).GetConstructor(argTypes), argValues)
);

_myModule.SetCustomAttribute(new CustomAttributeBuilder(
    typeof(DebuggableAttribute).GetConstructor(argTypes), argValues)
);
最后,在发出IL时,调用标记以下IL指令的行

使DLR呼叫站点可调试对我来说似乎很奇怪-通常您的呼叫站点不会包含任何用户代码。相反,它将包含执行操作的代码,并且没有与该代码关联的源代码。但是,假设您真的希望有一些与您正在为呼叫站点生成的表达式树相关联的内容。要做到这一点,你需要做两件事。首先是将调试信息存储在表达式树中–您可以使用。下一步是将该方法编译为可调试方法,并将该委托提供给DLR

用于编译您需要使用的方法。您需要提供的
MethodBuilder
必须是在先前创建的可调试程序集中的类型中定义的静态方法

要向DLR提供该委托,您有两个选项。可能最简单的方法是实际返回一个调用已编译的可调试委托的表达式(仅通过常量保持该委托)。在调用站点上重写
BindDelegate
,并返回已编译的委托,这是一种更困难但在某些方面更优雅的方法。这就开始创建适当的参数
Expression
s并调用
Bind*
方法来生成表达式树


所有这些都是在DLR外层/IronPython/IronRuby中完成的——所有这些都可以在。您可以查看
CompilerHelpers.CompileToMethod
作为编译的示例,
Snippets
类(以及相关的
AssemblyGen
/
TypeGen
/
ILGen
类,用于创建可调试程序集,甚至DLR表达式树编译器(在
Runtime\Microsoft.Scripting.Core\Compiler
)中)查看发送行信息的示例。

太棒了-谢谢Dino!迫不及待地想测试一下。“让DLR呼叫站点可调试对我来说似乎很奇怪”-这可能是因为我混淆了术语。我想了解的是,我希望能够逐行遍历代码,包括“动态”位。因此,如果我有一些动态表达式,如foo.bar.do_it(),我希望在.do_it()和.bar处中断(就像在VS中使用C一样)尽管如此,在阅读了Mike Stall的博客之后,看起来提供行级的单步执行将是一项艰巨的任务,在方法输入时中断是一个简单的过程。