CallbackOnCollectedDelegate -当没有附加调试器时会发生什么

本文关键字:什么 调试器 CallbackOnCollectedDelegate | 更新日期: 2023-09-27 17:50:02

我正在尝试诊断客户端崩溃,到目前为止我们无法在调试环境中重现。

我试图确定CallbackOnCollectedDelegate MDA通知(由第三方代码产生)是否会导致崩溃,如果调试器没有附加。

所以,问题是,第三方代码中导致收集委托回调的问题可能是这种行为的原因-调试时的MDA和不调试时的客户端崩溃?

有关此MDA的信息:http://msdn.microsoft.com/en-us/library/43yky316(v=vs.80).aspx

CallbackOnCollectedDelegate -当没有附加调试器时会发生什么

如果您收到MDA警告,那么您肯定再现了问题。是的,如果没有调试器,这将是一个严重的崩溃,本机代码在进行回调时将爆炸。将从本机代码到托管代码的调用封送的存根不再存在。AVE的可能性很高,尽管不能100%保证,因为在存根被收集后重用内存位置时,它可能引用一个有效地址。随机代码执行则是故障模式。无论哪一种结果都过于丑陋,难以诊断,永远不要让它走到这一步。

这是由于没有存储对传递给本机代码的委托的引用而导致的。或者不让存储引用的对象存活,是一样的。垃圾收集器无法看到也不知道本机代码正在使用存根。事实上,CLR在收集委托时销毁存根,这就是它如何管理存根的内存分配。

这是由你来确保这不会发生。最常见的正确解决方案是将委托对象引用存储在私有static变量中。只有当你明确地告诉本机代码不再进行回调时,才将其设置回null。从不将其设置为null是很常见的。还要添加一个测试,以确保在分配变量之前它是空的,如果不是,则抛出InvalidOperationException。如果您需要额外的间接级别,那么使用GCHandle.Alloc(Object)。同样的方法,在你确定它是安全的之前不要调用Free()。