如何查看通过编译表达式树创建的委托的反汇编?

时间:2013-02-16 12:02:34

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

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

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

2 个答案:

答案 0 :(得分:2)

使用LambdaExpression.CompileToMethod(MethodBuilder)

然后,您可以将AssemblyBuilder保存到一个文件中,您可以在自己喜欢的.NET反汇编程序中查看该文件。

答案 1 :(得分:2)

我最终使用了leppie的基本建议,将表达式输出到外部程序集。然后,我使用反射器提取方法并将其粘贴到我自己的代码中。然后我运行了粘贴的方法,并检查了什么是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");
}

组装完成后,可以使用像反射器这样的工具来提取方法。