| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Общие вопросы > Странное падение |
| Автор: CynicRus 25.3.2015, 21:26 | ||||||
| Приветствую уважаемых форумчан. Если сервак, написанный на Delphi XE 3. Чистые сокеты + IOCompltitionPorts. Работает быстро, всё вроде хорошо. Но, проработав несколько часов - раз и зависон. Интервал между зависонами абсолютно рандомный, от 2 часов...а может сутки-двое простоять. При этом при отладке - отладчик показывает вообще какую-то ерунду. Эксепшн при дисконнекте пользователя, где следующий код:
Начинаем падение отсюда, со строки Conn.free - разрушение объекта, далее следуем в деструктор коннекта:
Оттуда - идём в очистку Buffer'а коннекта :
затем следуем в обработчик уже самой винды, и в конце концов получаем AccessViolation, а после нажатия на Ok - OSError 5, access denied. Есть у кого какие-нибудь мысли, как победить это дело? Я уже весь мозг себе сломал за неделю боёв с отладчиком |
| Автор: kami 25.3.2015, 22:35 |
| Ну и помимо того, что в деструкторах нужно inherited, иначе память не освободится окончательно, мысля про "некрасивый exit из try-finally" мне кажется привлекательной: TTCPServer.Disconnect -> вызов деструктора TTCPConnection -> в нем CloseSocket -> опять по цепочке в TTCPServer.Disconnect, но уже с отрабатывающим exit -> глюк |
| Автор: CynicRus 26.3.2015, 07:15 |
| А вот эту цепочку то я и не узрел UPD: да всё так же. +-. Причём, когда этот тред клинит - выходит такая картина. Сервер подключения принимает, и на этом всё. |
| Автор: CynicRus 26.3.2015, 11:14 | ||||
При падении - вот как выглядит стек:![]() TTCPServerBuffered.disconnet:
А ClientThread:
|
| Автор: kami 26.3.2015, 19:21 |
| Есть подозрение, что раз непонятно, почему возникет ошибка, значит мы видим следствие. А причина совершенно в другом месте. Например - кто-то портит память, которую потом пытаемся освободить, двойной вызов Free и т.п. Подключи FastMM в FullDebugMode, если подозрения имеют основание - он покажет всю подноготную |
| Автор: CynicRus 26.3.2015, 19:41 | ||
А дедлок не может вести к такому поведению? Или наоборот, где-то не хватает критсекции? Потому что я с эврикой весь код облизал, ни единой утечки:( |
| Автор: kami 26.3.2015, 21:51 | ||
Дед Лок к AV не приведет Эврикой не пользовался, да и утечки сейчас ни при чем - от утечек может быть OutOfMemory, но не AV. А эврика умеет находить такие вещи, как попытки обращения к освобожденной памяти? К примеру, у FastMM это выглядит так (перевод далеко не дословный): "произведена попытка обращения к памяти, которая ранее была освобождена. Сейчас будет AV" "Ранее эта память была задействована: " (тут стек методов, приведший к вызову конструктора или GetMem и т.п." "Потом память была освобождена:" (тут стек вызовов до деструктора и т.п.) "Текущий стек, который приведет к AV:"... |
| Автор: CynicRus 27.3.2015, 19:46 |
| Помедитировал ещё с отладчиком. И возникло у меня подозрение на рукописную хэш таблицу. Досталась от коллеги, который видимо писал этот класс во времена Delphi 7, когда о дженериках в Delphi ещё не мечтали. Так вот, подумал я - а может быть его просто выпилить, и заменить на дженерики? Выпилил, заменил. 6 часов - полёт нормальный, заодно сэкономил 11 мегабайт памяти в рантайме. В этом классе содержались указатели на объект, бывало, что содержался 1 и тот же указатель, под разными ключами. Так вот похоже, что из-за этой ерунды - я и получал неуловимый глюк. Когда объект уже освободился, а в хэш-таблице где-то чего-то недотиралось. Всем спасибо за внимание. PS: TDictionary рвёт ту самоделку в клочья-) |
| Автор: kami 29.3.2015, 10:49 | ||
Уже, наверное, нет возможности проверить, но было бы интересно - отловил бы FastMM это "недотирание" или нет... |