如何检索已编译方法的源文件?

时间:2010-04-09 13:53:23

标签: c# reflection

我真的被这个难过了!

StackFrame对象(MSDN Link)有一个GetFileName方法,它返回编译执行方法的源文件的原始路径(提供的符号已生成并包含在执行的程序集中)。看起来这些信息用于生成完整的异常文本。

如果方法当前没有执行,我正试图找到获取此信息的方法。我一直在寻找反射API,并没有找到一种方法来获取这些信息。我认为它必须在某处。

是否有其他人知道可以获取代码文件名的基于反射的方法(或实际上任何其他方法)?

感激地接受任何想法,评论或滥用。

非常感谢!

3 个答案:

答案 0 :(得分:4)

Reflection只能从程序集元数据中提供类型信息。获取地址需要.pdb调试文件和内存中函数的地址,由JIT编译器编译。假设方法甚至已编译,则无法在没有StackFrame.GetNativeOffset()方法或调试器接口的情况下获取地址。后一种方法无法在进程中工作,程序无法自行调试。

CLR没有任何问题,因为它可以在处理异常时从堆栈帧中检索方法地址。这仍然是一个不完美的艺术,它无法看到内联方法的地址。拥有这些堆栈帧是必需的第一步。

答案 1 :(得分:1)

您可以从.pdb文件中读取信息并自行评估。它包含您需要的所有数据。我还没有读完代码,但我的理解是:

  • 您可以通过反射
  • 从相关方法获取元数据标记
  • 您查询该令牌的pdb数据
  • pdb条目包含源文件名和行号

元数据标记是32位数字,由类型字节和序列号组成。该标记描述.NET程序集文件中的每个实体:类型,类型引用,方法,字段等。该数字比方法的完整命名空间,类型,方法名称和签名更有价值,并且更容易处理。但请注意,它是由编译器生成的,并且在每个构建中可能都不同,因此您始终需要来自同一构建的.pdb文件。

pdb文件包含有关哪个方法来自哪个源位置的IL偏移量的条目。如果您没有StackFrame但只有一个方法,您可能会找到有关该方法的多个条目,因此您可以使用具有最小偏移量的条目,也可以在定义该方法的源代码中描述整个范围。 / p>

以下是一些进一步阅读的链接,搜索词是“pdb2xml”,这是Microsoft的旧代码示例:

由于用于读取.pdb文件的.NET API需要具有可用的汇编文件,因此应在构建之后直接进行此转换,以使生成的XML文件真正可移植。

我实际上是在我的.NET日志记录解决方案FieldLog中构建此方法,以允许从发布版本的崩溃日志中解析源位置,并对来自混淆程序集的堆栈跟踪进行反混淆。

答案 2 :(得分:0)

使用RedGate Reflector反编译器检查包含该类的程序集。