使CLR/.NET语言可调试

19
有哪些资源可以使CLR/.NET语言可调试?我正在开发一个将ActionScript 3编译成IL的编译器,使用DLR CallSites和CallSiteBinders处理静态编程语言中的动态部分。我正在寻找任何关于如何使发出的IL映射回源代码的信息,同时我也想知道如何使动态调用站点映射回去。
因此,这实际上是两个问题: 1. 我该如何使IL可调试? 2. 我该如何使DLR调用站点可调试?
非常感谢您的帮助!
“调试性”方面我所需要的:
在附加的Visual Studio实例中: 1. 逐步执行代码 2. 查看本地变量 3. 查看堆栈跟踪
1个回答

22

要使IL可调试,需要将代码编译成可调试的程序集。但是这样做会有一个明显的缺点,即程序集将无法被GC收集。为了实现这一点,您可以使用 AppDomain.CurrentDomain.DefineDynamicAssembly 方法创建一个动态程序集,然后调用 DefineDynamicModule 方法在程序集中定义一个模块。为了使其可调试,您需要在模块上设置一些属性:

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指令时,最后调用MarkSequencePoint来标记以下IL指令的行。

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

要编译方法,您需要使用LambdaExpression<T>.CompileToMethod。您需要提供的MethodBuilder将需要是在您之前创建的可调试程序集中定义的某个类型中的静态方法。

要将该委托提供给DLR,您有两个选择。可能最简单的方法是实际上返回一个表达式,该表达式调用已编译的可调试委托(仅通过常量保留它)。但在某些方面更优雅的更困难的方法将覆盖调用站点上的BindDelegate<T>并返回已编译的委托。然而,这需要创建适当的参数Expression并调用Bind*方法来自己生成表达式树。

所有这些都是在DLR外层/IronPython/IronRuby中完成的-全部可在ironpython.codeplex.com找到。您可以查看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的博客之后,看起来提供逐行步进将是一项巨大的任务,而在方法入口处中断则很容易。 - Charles

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接