FastMM4、DebugGetMem中的偶尔访问冲突



我正在试图追踪访问违规。可重复性似乎是不确定的,而且很少,所以在我进一步讨论之前,我想检查一下我的一些假设。

在FastMM4(版本4.991)函数DebugGetMem中,在以下代码中引发了访问冲突:

if (ASize > (MaximumMediumBlockSize - BlockHeaderSize - FullDebugBlockOverhead))
    or CheckFreeBlockUnmodified(Result, GetAvailableSpaceInBlock(Result) + BlockHeaderSize, boGetMem) then
  begin
    {Set the allocation call stack}
    GetStackTrace(@PFullDebugBlockHeader(Result).AllocationStackTrace, StackTraceDepth, 1);
    {Set the thread ID of the thread that allocated the block}
    PFullDebugBlockHeader(Result).AllocatedByThread := GetThreadID; // ** AV Here
    {Block is now in use: It was allocated by this routine}
    PFullDebugBlockHeader(Result).AllocatedByRoutine := @DebugGetMem;

例外是:

Project station.exe引发异常类$C0000005,提示"访问违规在0x01629099:读取地址0x66aed8f8"。

调用堆栈通常相同。它被从虚拟树视图上的一个绘制事件调用,我在其中调用Format('%s %s %s', [vid, node, GetName()]),尽管我怀疑这是真正相关的(除了格式分配动态内存)。

我使用FullDebugMode(显然)和CheckHeapForCorruption选项。

我还建立了以下内容:

  1. 打开CatchUseOfFreedInterfaces没有显示任何新内容。我仍然得到相同的访问冲突,没有额外的诊断。
  2. 我曾经用FullDebugModeScanMemoryPoolBeforeEveryOperation := True重现了崩溃,虽然我不记得CatchUseOfFreedInterfaces在这种情况下是开还是关。
  3. 这不是线程并发问题;我的应用程序是单线程的。(事实上,这并不完全正确。我正在使用Virtual TreeView,它创建了一个隐藏的工作线程,但如果这真的是原因,那么错误是在Virtual TreeView,而不是我的代码,这是相当不可能的。

我认为正确吗,尽管CheckHeapForCorruption没有捕获任何东西,这个异常只能是由于我的代码损坏堆?还有其他什么原因会导致FastMM4以这种方式崩溃吗?

有什么建议可以进一步诊断,甚至使崩溃更容易重现吗?

虽然看起来很奇怪,但这是正常的行为。如果您切换到CPU视图,您将看到指令指针位于FastMM_FullDebugMode.dll模块内。FastMM的一些调试功能在设计上可能会引发访问冲突。如果你继续执行,你会发现你的应用程序运行正确。

以这种方式中断调试会话是非常令人沮丧的。我与FastMM的作者就一个相关问题进行了一些讨论。似乎FastMM调试DLL被设计成以这种方式工作,结论是没有很多可以做的事情来阻止这些外部异常被提出。

如果有人认识到这种挫折,并有一个好的解决方案,我将永远感激。

相关内容

  • 没有找到相关文章

最新更新