【问题标题】:Debugging a .net Compiler调试 .net 编译器
【发布时间】:2012-03-25 20:13:44
【问题描述】:

我目前正在开发一种语言(外部字节码)的编译器,并且正在使用System.Reflection.Emit

现在,当我在反射器中打开生成的程序集时,一切看起来都很好,并且它重新编译为 C# 也很好(并运行),但是当我尝试运行生成的主函数时,我得到一个 @ 987654322@:

“公共语言运行时检测到无效程序。”

可能只是一个操作码导致了问题,但是,由于该主函数使用了 100 多个操作码,我无法确定是哪个操作码导致了问题。

每个操作码都非常复杂,因此手动测试每个操作码是不行的。

有没有办法让 .NET 告诉我它在函数的哪个位置检测到无效程序?

如果没有,我可以使用其他工具来确定问题的根源吗?

【问题讨论】:

  • 你试过 peverify.exe 吗?
  • 这正是我想要的。事实证明,当我执行 And & Or 指令时,我并没有思考,结果是不同的分支在堆栈上留下了不同数量的对象。

标签: .net debugging compiler-construction


【解决方案1】:

我最好把这个写下来作为答案。您可以使用PEVerify tool 执行程序集验证。它是 Windows SDK 工具的一部分,运行它的最佳方式是从 Visual Studio 命令提示符 peverify.exe 命令。您需要使用 /il 命令行选项运行它来检查您生成的 IL,使用 /md 来验证程序集元数据。

您将从该工具中获得更好的诊断结果,抖动生成的运行时异常信息太少,无法确定确切的错误。我不能保证它会执行与抖动相同的exact检查,这些是不同的代码块,并且抖动比静态分析有一点优势。然而,该工具是专门为您的用例设计的,即编写 IL 生成器的人。我将引用 MSDN 文章中的承诺:

Peverify.exe 基于数据流分析以及数百条关于有效元数据的规则列表执行全面的 MSIL 验证检查。有关 Peverify.exe 执行检查的详细信息,请参阅 Windows 软件开发工具包 (SDK) 中工具开发人员指南文件夹中的“元数据验证规范”和“MSIL 指令集规范”。

事实证明它对你很有效,这很酷:)

【讨论】:

  • PEVerify 肯定不会执行与抖动相同的检查。例如,it seems the jitter doesn't mind if the .maxstack is wrong,但 PEVerify 将其显示为错误。
  • @svick - 是的,我在玩它时也注意到了一些差异。这就是为什么我将免责声明放在我的答案中,微软文档中没有明确说明。关键是它不承诺执行完全相同的检查。否则,静态代码分析肯定是一个更难的问题,如果不有害,抖动可能会让事情滑落。
猜你喜欢
  • 1970-01-01
  • 2010-09-25
  • 2012-11-15
  • 1970-01-01
  • 1970-01-01
  • 2016-03-28
  • 1970-01-01
  • 2011-05-01
  • 2016-06-19
相关资源
最近更新 更多