【问题标题】:How do I view the disassembly of a delegate created by compiling an expression tree?如何查看通过编译表达式树创建的委托的反汇编?
【发布时间】:2013-02-01 08:02:14
【问题描述】:

我想看看 .Net 的即时编译器生成的 x86 程序集。我知道how to do this for "normal" code,提前编译,但不知道如何处理运行时动态生成的代码(我正在使用表达式树)。

我什至不确定要尝试什么。例如,通过编译表达式树创建的委托指向一个地址,但我不知道用什么来查看该地址的内容。

【问题讨论】:

    标签: c# .net expression-trees jit disassembly


    【解决方案1】:

    使用LambdaExpression.CompileToMethod(MethodBuilder)

    然后您可以将 AssemblyBuilder 保存到您可以在您最喜欢的 .NET 反汇编程序中检查的文件中。

    【讨论】:

    • 抖动处理运行时生成的 CIL 的方式是否与从程序集中加载的 CIL 完全相同?例如,如果有启发式算法在其中一种情况下进行更多优化怎么办?
    • 您要查看 JIT 程序集还是 IL?我的回答不适用于前者。从任何地方加载的 IL 应该被同等对待。
    • 我猜你可以在这种情况下使用调试器。不太清楚该怎么做;p
    【解决方案2】:

    我最终使用了 leppie 的基本建议,将表达式输出到外部程序集。然后,我使用反射器提取方法并将其粘贴到我自己的代码中。然后我运行 paste 的方法,并检查了什么是 jitted。这可能不是 100% 准确,但它至少给出了一个指示。

    这里有一些用于写出方法的代码(生成的程序集与可执行文件位于同一目录中):

    /// <summary>
    /// Writes an assembly, containing the given method, to the working directory.
    /// The assembly, type, and method are named based on the given hash name.
    /// </summary>
    public static void WriteMethodToAssembly<T>(Expression<T> method, string hashName) {
        var assemblyName = new AssemblyName(hashName);
        var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
        var moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name, assemblyName.Name + ".dll");
        var typeBuilder = moduleBuilder.DefineType(hashName, TypeAttributes.Public);
        var methodBuilder = typeBuilder.DefineMethod("Run" + hashName, MethodAttributes.Public | MethodAttributes.Static);
        method.CompileToMethod(methodBuilder);
    
        typeBuilder.CreateType();
        assemblyBuilder.Save(hashName + ".dll");
    }
    

    组装完成后,您可以使用反射器之类的工具来提取方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-30
      • 1970-01-01
      • 1970-01-01
      • 2023-03-05
      • 2011-03-02
      • 2019-06-09
      • 2011-03-07
      • 1970-01-01
      相关资源
      最近更新 更多