Ruu*_*zer 5 .net reflection jit ngen sos
在过去的几周里,我一直在玩非托管的.NET调试API.
虽然MSDN记录了接口本身,但为了找到如何以任何有意义的方式实际使用它们,我使用了各种博客(主要是Mike Stall)和CLR Managed Debugger示例中的托管包装器以及ILSpy源代码.最后,我能够将我的测试程序附加到正在运行的进程,设置断点并点击它们.
我接下来要做的就是点击这样一个断点,读取相关对象实例的一个字段.通过禁用加载NGEN的程序集(环境设置'COMPLUS_ZAPDISABLE = 1')并禁用JIT优化(又称'.ini文件技巧' ),当调试目标方法尚未进行NGEN或JIT时,这可以正常工作).
但是,当我尝试使用我理想的目标 - 零售优化(NGEN/JIT'ed)代码时 - 它不起作用.例如:我可以在命中入口断点时仍然检索方法参数的数量,但我无法获得第一个参数本身(调试API抛出异常).
现在,我想这是因为调试API应该是独立于平台的,在这种情况下,程序集不再存在.但是如果我接受这个平台依赖于英特尔的那个怎么办:据我所知CLR使用fastcall调用约定,在这种情况下,ECX寄存器包含第一个方法参数(成员函数的隐式'this'引用) .
我测试了这个,实际上在击中断点时,ECX包含NGEN的组件中的OBJECTREF(对象实例的地址).
现在,读取实例字段的最后一步是检索相对于此指针的字段偏移量,这就是我被卡住的地方,因为我似乎无法找到CLR如何在本机代码生成期间打包实例字段.
我意识到这可能是CLR版本/实现依赖,但显然有方法,因为带有SOS扩展的WinDbg能够找到这种布局.如果没有通过调试API,我能以某种方式利用SOS.dll吗?
对于你的第一个问题,你找不到参数/局部变量的原因是你正在调试优化的代码。优化的代码不允许跟踪 args/locals。
至于你的第二个问题,你需要在WinDbg中使用SOS.dll SOSEX.dll或PSSCOR2/4.dll或在Visual Studio中使用SOS/PSSCOR来读取对象的字段。
编辑:我现在看到您想从代码中执行此操作。这需要使用数据访问 (DAC) API,但不幸的是,该 API 没有文档记录。