使CLR / .NET语言可调试有哪些资源?我正在开发一个ActionScript 3 to IL编译器,该编译器使用DLR CallSite和CallSiteBinders处理原本为静态的编程语言的动态方面。我正在寻找有关使发出的IL映射回源代码的任何信息,并且我也想知道如何使动态调用站点也映射回源代码。

因此,这最终是两个问题:


如何使IL可调试?
如何使DLR呼叫站点可调试?


任何帮助将不胜感激!

我在寻找“可调试性”方面的内容

在附加的Visual Studio实例中:


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

最佳答案

为了使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中)作为发出行信息的示例。

10-07 13:22
查看更多