我有一个奇怪的错误,当删除一个特定对象时,delete
永远不会返回。相反,它似乎花时间Sleep()
在一个永久循环中调用。这是调用堆栈:
:7723fd71 ntdll.ZwDelayExecution + 0x15
:767c4498 KERNELBASE.Sleep + 0xf
:21495359 BORLNDMM.@Borlndmm@SysFreeMem$qqrpv + 0xb5
:32aaa3e5 CC32100MT._free + 0xd
:32a020b2 CC32100MT.@$bdele$qpv + 0x1e
[My code]
运行时,它返回SysFreeMem
(从不返回)并再次从内部free
调用,永久循环。Sleep
SysFreeMem
我的代码非常简单:它是一个 VCL 事件处理程序,一个微调框刚刚更改,一个设置对象更新,并且它所做的临时设置正在被删除:
delete poNewSettings;
这段代码一两年没有改变,设置类也有一段时间没有改变,它基本上是一个包含许多设置的巨大的类似结构的对象。它有一个编译器生成的析构函数。单步执行代码显示了一些删除字符串和其他 std:: 对象的调用,然后在单步执行下一个函数(即在 IDE结束时~basic_string()
,在右大括号处按 F7 )时,它似乎冻结了}
从不显示。冻结是它在 Sleep() 中。此代码在主线程中运行。
我尝试使用 CPU 视图来推断调用 Sleep() 的延迟,但无法发现它 - 恐怕我还没有完全掌握 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()
- 一个后台任务正在运行,它正在检查它是否需要工作(它不必)并且正在休眠 100 毫秒以再次检查。分配和免费用于文件夹路径的字符串。虽然程序中还有其他线程,但它们都被阻塞等待做某事,这次使用WaitForSingleObject
或类似的。此后台任务线程每 100 毫秒唤醒一次(从睡眠中返回);我没有看到(还没有!)它如何影响另一个线程的delete
.
据我所知,没有其他线程正在删除或分配任何东西。CC32100MT._malloc
我在,CC32100MT._free
和中放置了断点CC32100MT._realloc
。运行时没有其他线程中断,当暂停检查时,没有其他线程在任何这些调用中。
删除循环而不返回的原因可能是什么?
我正在使用: * RAD Studio 2010,完全更新 * 应用程序主要是 C++(C++ Builder),带有少量 Delphi。* 因为它使用的是 Embarcadero RTL,所以我认为它使用的是 FastMM
我添加了 Delphi 标签,因为它使用 Embarcadero RTL 和 FastMM,Delphi 人使用的次数比 C++ 人多得多。