Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > сообщение FastMM при завершении прилож.


Автор: kami 7.9.2012, 14:50
Доброго времени суток, уважаемые!

Второй день бьюсь над проблемой, которую мне выдает FastMM. Немного предистории:
Конфигурация: Delphi 2010, FastMM 4.97, MadExcept 3/0m.
Проблемное приложение: многопоточный сервер, все потоки - через стандартный TThread. Если завершить его (сервер, в смысле) при наличии активных подключений, то FastMM начинает ругаться (файл с руганью - во вложении).
При этом:
- все объекты нормально уничтожаются, каждый - в своем потоке (т.е. нет такого, что создан в одном, а уничтожен в другом потоке)
- финализация всех модулей (где есть секция финализации) проходит без замечаний. В секциях финализации освобождаются общие экземпляры классов, но на момент уничтожения они пусты.

После завершения финализации всего и вся - FastMM выдает вот это.

Не могу понять, в чем дело - я же не обращаюсь к уже освобожденным объектам, иначе FastMM отреагировала бы сразу же.

Есть какие-нибудь мысли?

Автор: DarkProg 7.9.2012, 15:12
А если отключить ругань со стороны FastMM и madExcept, и отключить всё игнорирование исключительных ситуаций в самой делфи не станет ли проще локализовать проблему?

Сейчас мне так кажется, по стеку в том что в каком-то потоке вы что-то создали, а оно несколько не уничтожилось, или уничтожилось что-то одно, а какой-то объект остаётся существовать...

У меня так было при включённой опции FreeOnTerminate, получались забавные ошибки и непонятные. Я отключил её и поток руками убиваю, так лучше при конкретно моей реализации.

Автор: kami 7.9.2012, 15:23
DarkProg, в том-то и дело, что при отключении FastMM всё становится прекрасно - приложение якобы завершается нормально.
Ведь судя по логу, FastMM выбрасывает ошибку уже на самом завершающем этапе - когда происходит удаление самого менеджера памяти FastMM, т.е. в своей, последней секции финализации. На этот момент уже ничего от программы и ее объектов не осталось.

Сейчас вот убрал вообще весь код из initialization/finalization. Не помогло.

Цитата(DarkProg @  7.9.2012,  15:12 Найти цитируемый пост)
У меня так было при включённой опции FreeOnTerminate

Не пользуюсь. Из-за нее действительно могут быть проблемы, гораздо лучше самому контролировать. Да и в этом случае выскочило бы AV (ну, это мечты, конечно ).

Сейчас пытаюсь понять, чем же может отличаться завершение программы без активных TCP подключений от имеющей таковые...

Цитата(DarkProg @  7.9.2012,  15:12 Найти цитируемый пост)
и отключить всё игнорирование исключительных ситуаций в самой делфи 

Это как и где отключается? Не включал ничего в этом духе...

Автор: DarkProg 7.9.2012, 15:33
Цитата(kami @  7.9.2012,  16:23 Найти цитируемый пост)
Это как и где отключается? Не включал ничего в этом духе... 

Обычно если галочка есть, то при исключении, которое обрабатывается ничего не происходит(ну или происходит), а вот без обработчика вылетает сообщение где много букав, а толку мало.
Оно включается если при вылете Except'а под отладчиком, в диалоге поставить галочку "ignore exception"
Отключается очень просто Tools->Options->Debugger Options->Language Exceptions, и там снять все галочки.

Цитата(kami @  7.9.2012,  16:23 Найти цитируемый пост)
Сейчас пытаюсь понять, чем же может отличаться завершение программы без активных TCP подключений от имеющей таковые...

Тем что возможно обработчики каким-то чудом ещё работают...(бред больного человека, но всё же  smile )

P.S. вроде в 2010 там также было всё расположено

Автор: kami 7.9.2012, 23:01
Цитата(DarkProg @  7.9.2012,  15:33 Найти цитируемый пост)
Отключается очень просто Tools->Options->Debugger Options->Language Exceptions, и там снять все галочки.

Не, я такими вещами не балуюсь smile Как стояло по умолчанию игнорировать только Indy, так и стоит. Полностью солидарен в этом с Delphi - я тоже игнорирую индейцев.

В общем, разобрался и нашел. Как обычно - совсем не там, куда указывалось FastMM. Хотя, надо признать - причина лежала рядом, совсем рядом.

Порядок разбора был следующим:
0. Ошибка стабильная, повторяется 1:1 при одинаковых действиях с программой (огромная удача, если честно).
1. Проверил, что при нормальном завершении TCP соединения ошибок не возникает, а если завершение соединения вызывано завершением работы сервера (прошу прощения за тавтологию) - то ошибка имеет место быть.
2. Промежуточный вывод - проблема действительно в коде обработчиков закрытия сокетов и "окололежащих с ними".
3. Просмотр всего кода, относящегося к завершению соединения с обдумыванием "а как оно действует при завершении программы"
4. Нашел узкий участок - относительно сложная связь экземпляров классов через события. Оказалось, что из-за этой связи может быть вызван метод принудительного завершения соединения, что само собой лишнее - соединение и так уже закрывается (программа-то завершается).
5. Ликвидировал двойной вызов (просто обnilил событие в деструкторе)
6. Наслаждаюсь. Правда, недолго - теперь проблема (уже другого плана) на клиенте  smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)