FastMM4,DebugGetMem中偶尔的访问冲突

时间:2014-03-27 10:52:08

标签: delphi access-violation fastmm heisenbug

我试图追踪访问冲突。再现性似乎是不确定的,并且很少见,所以我想在进一步研究之前检查一些我的假设。

在FaseMM4版本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 raised exception class $C0000005 with message 'access violation at 0x01629099: read of address 0x66aed8f8'.

调用堆栈通常是相同的。它是从虚拟树视图上的绘制事件中调用的,我称之为Format('%s %s %s', [vid, node, GetName()]),但我怀疑它是否真的相关(除了格式分配动态内存)。

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

我还建立了以下内容:

  1. 启用CatchUseOfFreedInterfaces并不会显示任何新内容。我仍然得到相同的访问冲突,并且没有其他诊断。
  2. 我曾使用FullDebugModeScanMemoryPoolBeforeEveryOperation := True复制了崩溃,但我无法记住CatchUseOfFreedInterfaces是否在此时开启或关闭。
  3. 它不是一个线程并发问题;我的应用程序是单线程的。 (实际上,这并不完全正确。我使用的是Virtual TreeView,它创建了一个隐藏的工作线程,但如果真的是这个原因那么bug就在Virtual TreeView中,而不是我的代码,这是相当的不可能的。)
  4. 我是否正确地认为,尽管CheckHeapForCorruption没有捕获任何内容,但此异常只能归因于我的代码破坏了堆?还有什么可能导致FastMM4以这种方式崩溃吗?

    有关进一步诊断,甚至使崩溃更可重复的任何建议吗?

1 个答案:

答案 0 :(得分:5)

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

以这种方式中断调试会话可能会非常令人沮丧。我had some discussion with the FastMM author处理了一个相关问题。似乎FastMM调试DLL的设计工作方式是这样的结论是,为了阻止引发这些外部异常,可以做很多事情。

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