FastMM是否可能错误地报告访问冲突?

我有一个复杂的应用程序,在正常编译时按预期工作,但是在使用FastMM 4.97(最新版本)编译时关闭表单会产生访问冲突。当消息调度尝试处理用于已经销毁的表单上的按钮的消息时,AV就会发生。我还为项目启用了Eurekalog 6.1.0.1(最新版本)。在禁用FastMM的FullDebug模式的情况下执行相同的代码时,它不会捕获任何运行时异常。 在某些情况下,FastMM是否可能会改变EXE的行为,从而导致或错误地报告访问冲突? 这是FastMM错误报告:
--------------------------------2011/3/21 13:30:17--------------------------------
FastMM has detected an attempt to call a virtual method on a freed object. An access violation will now be raised in order to abort the current operation.

Freed object class: TftGenericButton80

Virtual method: Offset +80

Virtual method address: 4A1FF0

The allocation number was: 5628628

The object was allocated by thread 0xE80, and the stack trace (return addresses) at the time was:
403110 [System][@GetMem]
404F03 [System][TObject.NewInstance]
42E85D [FastMM4][CreateComponent]
42EAD9 [FastMM4][TReader.ReadComponent]
42FEE1 [Classes][TReader.ReadValue]
42ED86 [FastMM4][TReader.ReadDataInner]
42ECC5 [FastMM4][TReader.ReadData]
433802 [Classes][TComponent.ReadState]
4A21CE [Controls][TControl.ReadState]
4A5742 [Controls][TWinControl.ReadState]
48BCA0 [Forms][TCustomForm.ReadState]

The object was subsequently freed by thread 0xE80, and the stack trace (return addresses) at the time was:
40313B [System][@FreeMem]
404F21 [System][TObject.FreeInstance]
405339 [System][@ClassDestroy]
8AFBEF [....AdvShapeButton.pas][AdvShapeButton][TAdvCustomShapeButton.Destroy][1422]
4A5601 [Controls][TWinControl.Destroy]
48A9DD [Forms][TScrollingWinControl.Destroy]
48B9D8 [Forms][TCustomForm.Destroy]
48B9F2 [Forms][TCustomForm.Destroy]
404F67 [System][TObject.Free]
A9C42C [....fmWaitingList.pas][fmWaitingList][TfrmWaitingList.OnTanWaitingListItem][130]
A9D41B [fmWaitingListItem.pas][fmWaitingListItem][TfrmWaitingListItem.DoOnTanItem][142]

The current thread ID is 0xE80, and the stack trace (return addresses) leading to this error is:
8B2630 [....AdvShapeButton.pas][AdvShapeButton][TAdvCustomShapeButton.Click][3042]
4A4817 [Controls][TControl.WMLButtonUp]
4A4227 [Controls][TControl.WndProc]
7E42B401 [CallNextHookEx]
7E42B401 [CallNextHookEx]
7E42B372 [MoveWindow]
7E42B317 [MoveWindow]
7E42B326 [MoveWindow]
7E42B326 [MoveWindow]
7E4278D0 [GetWindowTextLengthW]
7E4278E0 [GetWindowTextLengthW]

Current memory dump of 256 bytes starting at pointer address 7FEB5F00:
90 8C AD 00 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80
80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80
80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80
80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80
80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80
80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80
80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80
80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80
  Œ  ­  .  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €
€  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €
€  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €
€  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €
€  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €
€  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €
€  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €
€  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €
    
已邀请:
它没有报道AV;它正在创建一个虚假的AV异常,以使你的进程停止,因为它正在进行的道路 - 访问已删除的对象 - 经常导致数据损坏,这更糟糕。 问题不是访问违规;问题是试图在已经被释放的按钮上调用
Click
方法。只是从查看此堆栈跟踪看起来,您或其他人已经安装了一个挂钩,该挂钩持有对按钮的引用,并且在窗体被销毁后不会自行更新。这就是我开始寻找的地方。     
没有能够看到你的代码有点棘手。但是从堆栈跟踪中,它看起来好像你可能在处理发往该对象的消息的过程中破坏了一个
TAdvCustomShapeButton
实例。 开始检查的好地方应该是当前与
TfrmWaitingList.OnTanWaitingListItem
事件挂钩的方法。 你说关闭表格时会发生这种情况。 我假设您的表单在关闭时被销毁(不是简单地隐藏),因此它会破坏表单所拥有的所有对象。 表格是如何关闭的?你可能想要考虑Form.Release。     
我发现FastMM在这方面非常可靠。 如果在发布模式下运行,99.9%的时间在释放对象上调用方法都没有问题。 0.1%的时间只会出现在您最有价值的客户机器上! 所以,我敢打赌,这是一个问题。实际上很容易跟踪,因为FastMM为您提供了所有调用堆栈,它们确切地显示了它是如何发生的。您只需要仔细了解详细信息。 现在,您可能会问,如何在已释放的对象上调用方法?好吧,当你释放一个对象时,你将内存返回给内存管理器。但是内存管理器通常会保留该内存并等待重新使用它的适当时机。至关重要的是,它不会立即将其返回系统,因为这样做很昂贵(需要很长时间)。 这是使内存管理器快速运行的原因,但它也会导致错误,例如调用被屏蔽的自由对象上的方法。如果内存已返回系统,则此类操作将导致实际的访问冲突。这就是我所说的大部分时间,在内存管理器处于发布模式的情况下,这样的bug不会浮出水面。 在我看来,这是FastMM的最佳功能之一,并且注意这个警告将为您节省未来的痛苦。试图在现场追踪这样的问题是非常困难的。使用FastMM提供的信息进行修复通常很简单。     

要回复问题请先登录注册