5

通常のコンパイルでは期待どおりに動作する複雑なアプリケーションがありますが、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
  Œ  ­  .  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €
€  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €
€  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €
€  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €
€  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €
€  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €
€  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €
€  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €
4

3 に答える 3

13

AV を報告しているわけではありません。プロセスを金切り声で停止させるために、偽の AV 例外を作成しています。これは、削除されたオブジェクトへのアクセスが頻繁にデータの破損につながるためです。これはさらに悪いことです

問題はアクセス違反ではありません。Click問題は、すでに解放されているボタンで何かがメソッドを呼び出そうとしていることです。このスタック トレースを見ると、ボタンへの参照を保持しているフックがインストールされていて、フォームが破棄されると適切に更新されないように見えます。そこから探し始めました。

于 2011-03-21T19:40:04.570 に答える
7

コードを見ることができずに少し注意が必要です。TAdvCustomShapeButtonしかし、スタック トレースからは、そのオブジェクト宛てのメッセージを処理している最中にインスタンスを破棄しているように見えます。

TfrmWaitingList.OnTanWaitingListItemチェックを開始するのに適した場所は、現在イベントにフックされているメソッドです。

フォームを閉じるときにこれが発生すると言いました。
私はあなたのフォームが閉じられたときに(単に隠されているのではなく)破壊されていると仮定しているので、フォームが所有するすべてのオブジェクトを破壊します。

フォームはどのように閉じられていますか? 代わりに Form.Release を検討することをお勧めします。

于 2011-03-21T20:42:01.420 に答える
3

この点で、FastMM は非常に信頼できることがわかりました。

リリース モードで実行すると、99.9% の確率で、解放されたオブジェクトのメソッドを問題なく呼び出すことができます。0.1% の時間は常に、最も価値のある顧客のマシンでのみ発生します!

ですから、これが問題であることは間違いありません。FastMM は、それがどのように発生したかを正確に示すすべてのコール スタックを提供するため、追跡するのは実際には非常に簡単です。詳細を注意深く確認する必要があります。


さて、解放されたオブジェクトのメソッドを呼び出すにはどうすればよいでしょうか? オブジェクトを解放すると、メモリがメモリ マネージャに返されます。しかし、通常、メモリ マネージャはそのメモリを保持し、再利用するための適切な瞬間を待ちます。重要なのは、すぐにシステムに返さないことです。これはコストがかかるためです (かなりの時間がかかります)。

これにより、メモリ マネージャーが高速になりますが、マスクされているフリー オブジェクトでメソッドを呼び出すなどのエラーも発生します。メモリがシステムに返された場合、そのようなアクションは実際のアクセス違反になります。これは、ほとんどの場合、メモリ マネージャーをリリース モードにすると、このようなバグが表面化しないことを意味します。

私の見解では、これは FastMM の最高の機能の 1 つであり、この警告に注意を払うことで、将来の負担を軽減できます。このような問題を現場で追跡することは非常に困難です。通常、FastMM が提供する情報を使用して修正するのは簡単です。

于 2011-03-21T19:39:14.633 に答える