2010-03-26 2 views
1

Я тестировал свое приложение с FastMM и FullDebugMode, потому что у меня были проблемы с остановкой.Почему блок «меню» завершен слишком рано?

После решения проблемы моих собственных проблем FastMM начала жаловаться на вызов виртуального метода на освобожденном объекте в TPopupList. Я попытался перенести блок меню как можно раньше в приложениях, чтобы он был финализирован последним, но это не помогло. Это настоящая проблема, ошибка в vcl или ложная тревога от FastMM?

Вот полный отчет FastMM:

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: TPopupList 

Virtual method: Offset +16 

Virtual method address: 4714E4 

The allocation number was: 220 

The object was allocated by thread 0x1CC0, and the stack trace (return addresses) at the time was: 
403216 [sys\system.pas][System][[email protected]][2654] 
404A4F [sys\system.pas][System][System.TObject.NewInstance][8807] 
404E16 [sys\system.pas][System][[email protected]][9472] 
404A84 [sys\system.pas][System][System.TObject.Create][8822] 
7F2602 [Menus.pas][Menus][Menus.Menus][4223] 
40570F [sys\system.pas][System][System.InitUnits][11397] 
405777 [sys\system.pas][System][[email protected]][11462] 
40844F [SysInit.pas][SysInit][[email protected]][663] 
7F6368 [PCCSServer.dpr][PCCSServer][PCCSServer.PCCSServer][148] 
7C90DCBA [ZwSetInformationThread] 
7C817077 [Unknown function at RegisterWaitForInputIdle] 

The object was subsequently freed by thread 0x1CC0, and the stack trace (return addresses) at the time was: 
403232 [sys\system.pas][System][[email protected]][2699] 
404A6D [sys\system.pas][System][System.TObject.FreeInstance][8813] 
404E61 [sys\system.pas][System][[email protected]][9513] 
428D15 [common\Classes.pas][Classes][Classes.TList.Destroy][2914] 
404AB3 [sys\system.pas][System][System.TObject.Free][8832] 
472091 [Menus.pas][Menus][Menus.Finalization][4228] 
4056A7 [sys\system.pas][System][System.FinalizeUnits][11256] 
4056BF [sys\system.pas][System][System.FinalizeUnits][11261] 
7C9032A8 [RtlConvertUlongToLargeInteger] 
7C90327A [RtlConvertUlongToLargeInteger] 
7C92AA0F [Unknown function at towlower] 

The current thread ID is 0x1CC0, and the stack trace (return addresses) leading to this error is: 
4714B8 [Menus.pas][Menus][Menus.TPopupList.MainWndProc][3779] 
435BB2 [common\Classes.pas][Classes][Classes.StdWndProc][11583] 
7E418734 [Unknown function at GetDC] 
7E418816 [Unknown function at GetDC] 
7E428EA0 [Unknown function at DefWindowProcW] 
7E428EEC [Unknown function at DefWindowProcW] 
7C90E473 [KiUserCallbackDispatcher] 
7E42B1A8 [DestroyWindow] 
47CE31 [Controls.pas][Controls][Controls.TWinControl.DestroyWindowHandle][6857] 
493BE4 [Forms.pas][Forms][Forms.TCustomForm.DestroyWindowHandle][4564] 
4906D9 [Forms.pas][Forms][Forms.TCustomForm.Destroy][2929] 

Current memory dump of 256 bytes starting at pointer address 7FF9CFF0: 
2C FE 82 00 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 C4 A3 2D 0C 00 00 00 00 B1 D0 F9 7F 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C0 00 00 00 16 32 40 00 9D 5B 40 00 C8 5B 40 00 
CE 82 40 00 3C 40 91 7C B0 B1 94 7C 0A 77 92 7C 84 77 92 7C 7C F0 96 7C 94 B3 94 7C 84 77 92 7C 
C0 1C 00 00 32 32 40 00 12 5B 40 00 EF 69 40 00 BA 20 47 00 A7 56 40 00 BF 56 40 00 A8 32 90 7C 
7A 32 90 7C 0F AA 92 7C 0A 77 92 7C 84 77 92 7C C0 1C 00 00 0E 00 00 00 00 00 00 00 C7 35 65 59 
2C FE 82 00 80 80 80 80 80 80 80 80 80 80 38 CA 9A A6 80 80 80 80 80 80 00 00 00 00 51 D1 F9 7F 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C1 00 00 00 16 32 40 00 9D 5B 40 00 C8 5B 40 00 
CE 82 40 00 3C 40 91 7C B0 B1 94 7C 0A 77 92 7C 84 77 92 7C 7C F0 96 7C 94 B3 94 7C 84 77 92 7C 
, þ ‚ . € € € € € € € € € € € € € € € € Ä £ - . . . . . ± Ð ù 
. . . . . . . . . . . . . . . . À . . . . 2 @ . [ @ . È [ @ . 
Î ‚ @ . < @ ‘ | ° ± ” | . w ’ | „ w ’ | | ð – | ” ³ ” | „ w ’ | 
À . . . 2 2 @ . . [ @ . ï i @ . º  G . § V @ . ¿ V @ . ¨ 2 | 
z 2 | . ª ’ | . w ’ | „ w ’ | À . . . . . . . . . . . Ç 5 e Y 
, þ ‚ . € € € € € € € € € € 8 Ê š ¦ € € € € € € . . . . Q Ñ ù 
. . . . . . . . . . . . . . . . Á . . . . 2 @ . [ @ . È [ @ . 
Î ‚ @ . < @ ‘ | ° ± ” | . w ’ | „ w ’ | | ð – | ” ³ ” | „ w ’ | 

Я использую Delphi 2007 и FastMM 4,97.

Редактировать 1: Я думаю, главная проблема здесь в том, почему Classes.StdWndProc вызывает Menus.TPopupList? Копание стека вызовов внутри отладчика показывает, что System.FinalizeUnit вызывается три раза, затем он переходит к SysUtils.ShowException, который пытается отобразить MessageBox и после связки вызовов user32.dll мы заканчиваем классы. StdWndProc.

Редактировать 2: У меня была проблема с интерфейсами, исправление которых заставило эту проблему уйти. Объект с интерфейсом был освобожден, но ссылка была выпущена позже. Когда интерфейс был выпущен, произошло исключение, которое я изначально каким-то образом проигнорировал. Выпуск интерфейса, вероятно, исказил что-то, что вызвало все другие проблемы.

ответ

2

Убедитесь, что FastMM4 - это ПЕРВАЯ строка в предложении использования вашего проекта (проект | Просмотр источника). Если его там нет, добавьте его.

2

Похоже, что одна из ваших форм будет уничтожена после того, как Menus.pas будет завершен. Если в вашей форме есть меню на нем, вероятно, должно быть меню в своем использует список в разделе , что должно сделать это невозможным.

Единственный раз, когда я видел такие проблемы, как этот всплывающий (без каламбура), используется при использовании пакетов. Возможно, вы используете DPK с плагином, который добавляет всплывающее меню или пункты меню в вашу программу? Окончание финализации может сделать некоторые странные вещи для вашей программы, если вы не будете осторожны.

В любом случае, решение, вероятно, должно быть утилизировано из меню самостоятельно до того, как меню будет завершено. Когда пришло время выключить программу, вызовите «Свободный» в своем всплывающем меню и посмотрите, разрешает ли эта проблема.

+0

Да, это была точка вопроса, почему menus.pas завершается слишком рано, прежде чем все формы будут завершены. Я не уверен в пакетах, я думаю, что такого не должно быть, но мне нужно будет проверить. – Harriv

3

Я видел такие проблемы с Delphi 2007 раньше. Иногда компилятор запутывается и генерирует неправильный порядок инициализации или завершения. К сожалению, я никогда не мог создать воспроизводимый тестовый пример для отправки людям CodeGear/Embarcadero.

Всякий раз, когда это произошло, помогала полная перестройка.

7

Эта ситуация может произойти, когда устройство завершит работу над другим устройством, от которого оно косвенно зависит.

Для Exemple, возьмите следующий блок:

unit Unit1; 
interface 
uses 
    Contnrs; 

var 
    ItemHolder : TObjectList; 

implementation 

initialization 
    ItemHolder := TObjectList.Create(True); 
finalization 
    ItemHolder.Free; 
end. 

Это устройство только непосредственно зависит от Contnrs. По этой причине delphi обеспечит завершение работы этого устройства до Contnrs. Если ObjectList содержит TForms, Delphi не гарантирует, что Unit1 будет завершен до форматирования единицы.Если при закрытии приложения остаются какие-то формы, TObjectList (поскольку он владеет объектом) освобождает содержащиеся в нем элементы (Call TForm.Free). Но поскольку Unit1 не зависит от TForm, возможно, что форма Forms уже завершена и что TForm.Destroy больше не находится в памяти.

Вот почему вам нужно быть очень осторожным в том, что вы делаете в разделах доработки.

Я не уверен, что это источник вашей проблемы, но я бы посмотрел именно так.

0

Update: это лишь частичное временное решение

Обход: В главной форме приложения написать

finalization 
    FreeAndNil(PopupList); 
end. 

бесплатно PopupList и установить на ноль, так что PopupList.Free в menus.pas будет ОК.

Смежные вопросы