【发布时间】:2011-04-10 08:57:09
【问题描述】:
我正在寻找有关如何在使用 Delphi VCL 中的 MS XML 包装器的应用程序中调试崩溃的提示。我怀疑内存损坏,或者对象和接口之间发生了某种晦涩难懂的事情,例如引用计数错误或堆损坏。实际上,问题是:如何调试这样的崩溃?
此特定代码在内部大量使用并扩展了基本 XmlIntf 接口 (IXMLNode)。 ISomethingCustom 是一个扩展 IXMLNode 的接口。问题发生在我们在某个递归函数中崩溃的地方,该函数传递了一个 ISomethingCustom,它也是(或在接口方面也支持)IXMLNode。
boolean UtilityFunction( aNode: ISomethingCustom ):Boolean;
begin
if not Assigned(aNode) then exit; // this works. great.
if not Assigned(aNode.ParentNode) then exit; // this DOES NOT WORK.
// code that blows up if aNode.ParentNode is not assigned.
end;
情况是 aNode 也是 IXMLNode,并且 IXMLNode.ParentNode 值被赋值(不是 nil),但它指向一个可能已被释放、销毁或以某种方式损坏的 COM 对象。我试图弄清楚当接口指针看起来有效时发生了什么,但它背后的对象已经以某种方式被核了。
检查 Assigned(aNode.ParentNode) 会返回 TRUE,即使您尝试在调试器中进行强制转换(仅在运行时,而不是在代码中),如下所示:
- 检查/评估节点
- 检查/评估 TInterfacedObject(aNode).ClassName (至少在 Delphi 2010 中有效!)
- 现在投射 TWhateverClassNameYouGotBefore(aNode)。
- 在调试器中,我现在看到这是 NIL。这可能意味着 神奇的“铸造界面回到 对象”的新功能 delphi 2010,失败了。
我相信我正在尝试调试由于引用计数问题而导致堆损坏或堆上的 COM 对象损坏的问题。
我真的认为没有人应该出现这样的情况:接口看起来有效,但下面的对象已被删除。我真的很想知道该怎么做,发生了什么。
【问题讨论】:
-
检查 Assigned(aNode.ParentNode) 返回 TRUE,即使 TNode(aNode).ParentNode 实际上是 NIL。
-
一定是做坏事了。在我注意到某些东西被破坏之前不会故意进行任何转换,然后我在调试器的评估表达式中进行转换,只是为了看看我是否能看到关于接口背后的任何内容。 :-)