使CLR/.NET语言可调试

Cha*_*les 19 compiler-construction debugging cil dynamic-language-runtime dynamic

有什么资源可以使CLR/.NET语言可调试?我正在开发一个ActionScript 3到IL编译器,它使用DLR CallSites和CallSiteBinders来处理静态编程语言的动态方面.我正在寻找有关将发出的IL映射返回源代码的任何信息,我也想知道如何使动态调用站点也能映射回来.

所以这最终有两个问题:

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

任何帮助将不胜感激!

我正在寻找的"debuggabilty"

在附加的Visual Studio实例中:

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

Din*_*and 21

要使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)
);
Run Code Online (Sandbox Code Playgroud)

最后在发出IL时,您调用MarkSequencePoint以标记以下IL指令的行.

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

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

为了将该代表提供给DLR,您有两种选择.可能最简单的方法是实际返回一个调用已编译的可调试委托的表达式(只需通过常量保持它).更难但在某些方面更优雅的方式是覆盖BindDelegate<T>调用站点并返回已编译的委托.然后开始创建适当的参数Expression并调用Bind*方法来生成表达式树.

所有这一切都在DLR外层/ IronPython/IronRuby中完成 - 所有这些都可以在ironpython.codeplex.com上找到.您可以看一下CompilerHelpers.CompileToMethod编译的示例,Snippets类(以及用于创建可调试组件的关联AssemblyGen/ TypeGen/ ILGen类,甚至是DLR表达式树编译器(in Runtime\Microsoft.Scripting.Core\Compiler),以获取发出行信息的示例.