5

在过去的几周里,我一直在玩弄非托管 .NET 调试 API

虽然 MSDN 记录了接口本身,但为了了解如何以任何有意义的方式实际使用它们,我求助于各种博客(主要是Mike Stall 的)和CLR 托管调试器示例ILSpy 源中的托管包装器。最后,我能够将我的测试程序附加到正在运行的进程,设置断点并点击它们。

接下来我想做的是在遇到这样的断点时,读取相关对象实例的字段。当调试目标方法没有经过 NGEN 或 JIT 时,通过禁用加载 NGEN 程序集(环境设置“COMPLUS_ZAPDISABLE=1”)和禁用 JIT 优化(又名“.ini 文件技巧”),这可以正常工作)。

但是,当我对我的理想目标(零售优化(NGEN/JIT'ed)代码)进行相同尝试时,它不起作用。例如:我可以在点击入口断点时仍然检索方法参数的数量,但我无法获取第一个参数本身(调试 API 会引发异常)。

现在,我想这是因为调试 API 应该是平台独立的,在这种情况下,程序集不再是。但是,如果我接受这个平台对英特尔的依赖怎么办:据我所知,CLR 使用fastcall 调用约定,在这种情况下,ECX 寄存器包含第一个方法参数(成员函数的隐式“this”引用) .

我对此进行了测试,实际上在到达断点时,ECX 在 NGEN 的程序集中包含了 OBJECTREF(对象实例的地址)。

现在读取实例字段的最后一步是检索相对于该指针的字段偏移量,这就是我卡住的地方,因为我似乎无法找出 CLR在本机代码生成期间如何打包实例字段.

我意识到这可能取决于 CLR 版本/实现,但显然有办法,因为带有 SOS 扩展的 WinDbg 能够找到这种布局。如果不通过调试 API,我可以以某种方式利用 SOS.dll 吗?

4

1 回答 1

0

对于您的第一个问题,您找不到参数/本地变量的原因是您正在调试优化代码。优化的代码不允许跟踪 args/locals。

至于第二个问题,您需要在 WinDbg 中使用 SOS.dll SOSEX.dll 或 PSSCOR2/4.dll 或在 Visual Studio 中使用 SOS/PSSCOR 才能读取对象的字段。

编辑:我现在看到您想从代码中执行此操作。这需要使用数据访问 (DAC) API,不幸的是,该 API 未记录在案。

于 2013-01-07T12:43:53.230 回答