使CLR / .NET语言可以调试 [英] Making a CLR/.NET Language Debuggable

查看:143
本文介绍了使CLR / .NET语言可以调试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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




  • 如何使 / li>
  • 如何让 DLR调用网站可调试?



<任何帮助将非常感谢!



我正在寻找的debuggabilty



附加的Visual Studio实例:




  • 步骤代码

  • 查看当地人

  • 查看堆栈跟踪


解决方案

进入可调试组件。还有一个立即的缺点是,集会不会被GC收集。为此,您可以 AppDomain.CurrentDomain.DefineDynamicAssembly ,然后调用 DefineDynamicModule 并在程序集中定义一个模块。要使其可调试,您需要在其上设置一些属性:

  DebuggableAttribute.DebuggingModes attrs = 
DebuggableAttribute.DebuggingModes。默认|
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指令的行。 p>

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



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



为了将代理提供给DLR,您有两个选择。可能最简单的是实际返回一个表达式,它调用编译的可调试委托(只是通过常量保存)。更难,但在某些方面更优雅的方式是在调用站点上重写 BindDelegate< T> ,并返回编译的代理。开始创建适当的参数表达式 s并调用 Bind * 方法来产生表达式树。



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


What are some resources for making a CLR/.NET language debuggable? I'm developing an ActionScript 3 to IL compiler, which uses DLR CallSites and CallSiteBinders to handle the dynamic aspects of the otherwise static programming language. I'm looking for any information on making the emitted IL map back to the source code, and I'd also like to know how I can make the dynamic call sites map back as well.

So this is ultimately two questions:

  • How can I make the IL debuggable?
  • How can I make the DLR call sites debuggable?

Any help would be greatly appreciated!

What I'm looking for in terms of "debuggabilty"

Within attached Visual Studio instance:

  • Step through code
  • View locals
  • View stack trace

解决方案

To make IL debuggable you need to compile the code into a debuggable assembly. There's also an immediate downside in that the assembly will not be collectible by GC. To do this you do AppDomain.CurrentDomain.DefineDynamicAssembly, then you call DefineDynamicModule and define a module in the assembly. To make it debuggable you need to set some attributes on it:

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)
);

Finally while emitting the IL you call MarkSequencePoint to mark the lines for the following IL instructions.

Making DLR call sites debuggable seems weird to me – generally your call site is not going to contain any user code. Rather it will contain code to perform an operation and there is no source code associated with that code. But let's say you really want to have something to step through that's associated with the expression trees you're generating for a call site. To do that you'll need to do two things. First is store the debugging info in the expression tree – you do this using a DebugInfoExpression. The next is compiling the method into a debuggable method and providing that delegate to the DLR.

For compiling the method you need to use LambdaExpression<T>.CompileToMethod. The MethodBuilder that you'll need to provide will need to be a static method defined in a type in the debuggable assembly that you created earlier.

For providing that delegate to the DLR you have two options. Probably the easiest would be to actually return an expression which invokes the compiled debuggable delegate (just holding onto it via constant). The harder but in some ways more elegant way would be to override BindDelegate<T> on the call site and return the compiled delegate. That starts getting into creating appropriate argument Expressions and calling the Bind* methods to produce the expression tree your self though.

All of this is done in the DLR outer layer/IronPython/IronRuby – all available at ironpython.codeplex.com. You can look at CompilerHelpers.CompileToMethod as an example of doing the compilation, the Snippets class (and the associated AssemblyGen/TypeGen/ILGen classes for creating the debuggable assemblies, and even the DLR expression tree compiler (in Runtime\Microsoft.Scripting.Core\Compiler) for an example of emitting the line info.

这篇关于使CLR / .NET语言可以调试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆