更新:2007 年 11 月
编写不正确的探查器可能会造成循环引用自身,从而导致不可预知的行为。
通过查看 CLR 分析 API,会让人产生这样一个印象:即您可以编写包含托管组件和非托管组件的探查器,这些组件通过 COM 互操作或间接调用互相调用。
尽管从设计角度来说这是可行的,但分析 API 不支持托管组件。CLR 探查器必须完全处于非托管状态。尝试在 CLR 探查器中组合托管代码和非托管代码可能会导致访问冲突、程序故障或死锁。探查器的托管组件会激发事件回到其非托管组件,后者随后又将再次调用托管组件,从而导致循环引用。
CLR 探查器中唯一可以安全调用托管代码的位置是在方法的 Microsoft 中间语言 (MSIL) 体中。在函数的实时 (JIT) 编译完成之前,探查器可以在方法的 MSIL 体中插入托管调用,然后对其进行 JIT 编译(请参见 ICorProfilerInfo::GetILFunctionBody 方法)。这种技术可以成功地用于托管代码的选择性检测,或者用于收集有关 JIT 的统计信息和性能数据。
或者,代码探查器可以在调入非托管代码的每个托管函数的 MSIL 体中插入本机挂钩。这种技术可用于检测和覆盖。例如,代码探查器可以在每个 MSIL 块之后插入检测挂钩,以确保该块已执行。修改方法的 MSIL 体是一项非常细致的操作,有许多因素应考虑在内。