我有一个奇怪的错误,当删除一个特定的对象时,delete
永远不会返回。相反,它似乎花时间在永久循环中呼叫Sleep()
。这里的调用堆栈:什么会导致删除循环睡眠()并且永远不会返回Borland/Embarcadero RTL?
:7723fd71 ntdll.ZwDelayExecution + 0x15
:767c4498 KERNELBASE.Sleep + 0xf
:21495359 [email protected]@SysFreeMem$qqrpv + 0xb5
:32aaa3e5 CC32100MT._free + 0xd
:32a020b2 [email protected]$bdele$qpv + 0x1e
[My code]
运行时,它返回到SysFreeMem
(永不回free
)和SysFreeMem
内再次呼吁Sleep
,永久循环。
我的代码非常简单:它是一个VCL事件处理程序,一个纺纱器刚刚更改和设置对象更新,它所做的临时设置被删除:
delete poNewSettings;
此代码并没有改变一两年,也没有一段时间的设置类,这基本上是一个巨大的结构类对象包含大量的设置。它有一个编译器生成的析构函数。逐句通过代码显示了一些删除字符串和其他std :: objects的调用,然后在进入下一个函数时(即在~basic_string()
的末尾按下F7,在关闭大括号}
处),它似乎冻结IDE从不显示。冻结是它在Sleep()内。此代码正在主线程中运行。我试图使用CPU视图来推断睡眠()被调用的延迟,但无法发现它 - 我不完全放在x86汇编代码,恐怕。
另一个线程在Sleep
之内,可能与COM有关(应用程序是一个COM服务器,尽管目前没有使用COM)。它的整个调用堆栈是:
:7723fd71 ntdll.ZwDelayExecution + 0x15
:767c4498 KERNELBASE.Sleep + 0xf
:74c7d98d ; C:\Windows\syswow64\ole32.dll
:74c7d87a ; C:\Windows\syswow64\ole32.dll
:768133aa kernel32.BaseThreadInitThunk + 0x12
:77259ef2 ntdll.RtlInitializeExceptionChain + 0x63
:77259ec5 ntdll.RtlInitializeExceptionChain + 0x36
另外一个线程正在做一些积极分配和释放内存,并呼吁Sleep()
太 - 后台任务运行它检查是否需要工作(它不必)并且睡眠100ms再次检查。分配和空闲是用于文件夹路径的字符串。虽然程序中还有其他线程,但它们都被阻塞等待某些事情发生,这次使用的是WaitForSingleObject
或类似的。该后台任务线程每100ms唤醒一次(从睡眠中返回);我没有看到(还!)它是如何影响另一个线程的delete
。
据我所知,没有其他线程正在删除或分配任何东西。我在CC32100MT._malloc
,CC32100MT._free
和CC32100MT._realloc
中加入了断点。运行时没有其他人中断,并且在暂停检查时,其他任何线程都不在其中。
什么可能是删除循环和不返回的原因?
我正在使用: * RAD Studio 2010,完全更新 *应用程序主要是C++(C++ Builder),带有小的Delphi位。 *因为它使用了Embarcadero的RTL,我认为它是使用FastMM
我已经因为它使用Embarcadero公司RTL和FastMM,这是由德尔福的人比用C++的人多了不少使用添加了德尔福标签。
听起来好像你可能在堆空闲块列表中有一个循环循环的堆损坏。我对C++ Builder不熟悉 - 你能够启用FastMM调试标志吗? – 2013-03-08 18:03:58
感谢您的建议!我不确定FastMM调试模式。我*认为它使用fastMM的C实现 - 我以前在RTL源文件夹中看到过一个 - 而不是Delphi实现。坦率地说,我不太了解内部结构。 – 2013-03-08 18:09:29