FastMM4,DebugGetMem中偶尔的访问冲突

Ian*_*dby 10 delphi fastmm access-violation

我正在尝试追踪访问冲突.再现性似乎是非确定性的,并且很少见,因此我想在进一步研究之前检查一些我的假设.

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

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;
Run Code Online (Sandbox Code Playgroud)

例外是:

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;
Run Code Online (Sandbox Code Playgroud)

调用堆栈通常是相同的.它是从虚拟树视图上的paint事件中调用的,DebugGetMem虽然我怀疑它是否真正相关(除了Format分配动态内存).

我正在使用Format('%s %s %s', [vid, node, GetName()])(显然)和FullDebugMode选项.

我还建立了以下内容:

  1. 打开CheckHeapForCorruption并没有显示任何新内容.我仍然得到相同的访问冲突,没有其他诊断.
  2. 我曾经复制过这次坠机事件CatchUseOfFreedInterfaces,虽然我不记得FullDebugModeScanMemoryPoolBeforeEveryOperation := True在这个场合是打开还是关闭.
  3. 它不是线程并发问题; 我的应用程序是单线程的.(实际上,这不是真的.我正在使用Virtual TreeView,它创建了一个隐藏的工作线程,但如果真的是这个原因那么bug就在Virtual TreeView中,而不是我的代码,这是不太可能的.)

我是否正确地认为,尽管CatchUseOfFreedInterfaces没有捕获任何东西,但这个异常只能归因于我的代码破坏了堆?还有什么可能导致FastMM4以这种方式崩溃吗?

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

Dav*_*nan 8

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

以这种方式中断调试会话可能会非常令人沮丧.我在相关问题上与FastMM作者进行了一些讨论.似乎FastMM调试DLL设计为以这种方式工作,结论是没有太多可以做的来阻止引发这些外部异常.

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

  • 对.我刚才有一个,继续执行,显然一切都很好.哦,这个'问题'只浪费了两天时间.谢谢,大卫. (3认同)