我正在尝试追踪访问冲突。可重复性似乎是不确定的,而且很少见,所以我想在进一步讨论之前检查我的一些假设。
在 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 Workstation.exe 引发异常类 $C0000005,并带有消息“0x01629099 处的访问冲突:读取地址 0x66aed8f8”。
调用堆栈通常是相同的。它是从我调用的虚拟树视图上的绘制事件中调用的,Format('%s %s %s', [vid, node, GetName()])
尽管我怀疑这是否真的相关(除了 Format 分配动态内存)。
我正在使用FullDebugMode
(显然)和CheckHeapForCorruption
选项。
我还建立了以下内容:
- 打开
CatchUseOfFreedInterfaces
并没有显示任何新内容。我仍然遇到相同的访问冲突,并且没有额外的诊断。 - 我曾经用 重现了崩溃
FullDebugModeScanMemoryPoolBeforeEveryOperation := True
,虽然我不记得CatchUseOfFreedInterfaces
这次是打开还是关闭。 - 这不是线程并发问题;我的应用程序是单线程的。(实际上,这并不完全正确。我正在使用 Virtual TreeView,它创建了一个隐藏的工作线程,但如果这确实是原因,那么错误在 Virtual TreeView,而不是我的代码中,这不太可能。)
我是否正确地认为,尽管CheckHeapForCorruption
没有捕获任何东西,但这个异常只能是由于我的代码破坏了堆?还有什么其他可能导致 FastMM4 以这种方式崩溃的吗?
对进一步诊断有什么建议,甚至使崩溃更具重现性?