Как отладить сбой, который возникает только при завершении работы приложения? (Delphi)
Итак, после некоторых недавних изменений мы обнаружили, что одно из наших самых старых приложений иногда терпит крах при завершении работы. Это проявляется либо в форме сообщений "Ошибка выполнения 216", либо в сообщении из отчета об ошибках Windows, что приложение перестало работать. Приложение уже выпускает OutputDebugString
-массы на каждом шагу, а AFAICT весь наш собственный код правильно выполняется для завершения. Все деструкторы вызываются так же, как и все секции финализации и деструкторы класса, ни одна из которых не создает каких-либо исключений.
Кроме того, ни для madExcept, ни для FastMM4 Full Debug Mode, похоже, есть что-то, на что можно жаловаться (хотя это может быть ложным завершением, потому что авария может произойти даже до того, как будет запущен собственный код завершения этих компонентов).
Итак, что бы вы сделали? С чего бы вы начали?
Этот вопрос должен быть больше об общем подходе к этому классу проблем, чем о конкретном экземпляре, с которым я сейчас сталкиваюсь, поэтому я намеренно не учитываю детали. Не стесняйтесь спросить, думаете ли вы, что они могут иметь отношение к выбору подхода отладки, и я добавлю их позже.
Ответы
Ответ 1
Ошибка времени выполнения 216 означает, что у вас есть Av (нарушение прав доступа), а SysUtils уже прекратила переводить эти ошибки в исключения.
Сначала попробуйте: постройте с помощью отладочного DCU и посмотрите в системной системе, где возникает ошибка, установите там контрольную точку. надеюсь, вы можете поймать его в отладчике и работать оттуда.
Вероятно, у вас есть ошибка памяти (оборванный указатель, нулевая ссылка и т.д. и т.д. использование константы s-строки в уже завершенном модуле), и лучший трюк - проверить завершение после завершения sysutils. Вы можете сделать это, построив WITH debug dcu, установив точку останова на финализацию в sysutils и начните выполнять код до появления ошибки.
Ответ 2
Используете ли вы пакеты времени выполнения? Раньше я видел подобные проблемы. Если вы делитесь глобальными или интерфейсами между границами пакетов, вы должны убедиться, что все ссылки на классы, принадлежащие определенному пакету, будут очищены до того, как этот пакет будет выгружен; в противном случае они попытаются сделать виртуальные вызовы в памяти более недействительными.
Ответ 3
Ну, Ошибка выполнения 216 - проблема памяти (Нарушение доступа), похоже, вы ссылаетесь на какой-то объект, который не существует в данный момент времени.
Эмаркадеро пишет:
Приложения, использующие класс SysUtils, сопоставляют большинство ошибок времени выполнения с исключениями, которые позволяют вашему приложению разрешать ошибку, не прерывая
Вы пытались установить брекерскую точку в секции финализации Sysutils?
Я бы попробовал его с помощью Profocation распределения/памяти, не уверен, что вы найдете строку кода ошибки, но это может показать вам некоторые части вашего кода, в которых происходят проблемы с памятью.
Ответ 4
Вероятно, у вас проблема с указателем. Некоторое событие или метод пытается запустить объект, который больше не существует.
Ответ 5
"Ошибка выполнения 216" - это сама Windows, а не обработчик исключений Delphi. Я обнаружил, что это вызвано кодом, который выполняется в разделах инициализации и завершения блоков, которые выполняются перед обработчиком исключений Delphi. В частности. COM-объекты, которые необходимо разгрузить через код завершения, запущенный после того, как приложение Delphi завершилось, вызовут эту и подобные ошибки. Поэтому проверьте этот материал.
MNG
Ответ 6
Как и другие, сказано: 216 означает, что AV после отключения SysUtils. Обычно единственное, что останавливается после SysUtils (и есть шанс поднять AV) - это системный блок. В частности: менеджер памяти.
Таким образом, ошибка при запуске 216 при выключении обычно означает ошибку повреждение памяти в вашем приложении.
Это может быть очень легко решить - просто включите режим полной отладки в диспетчере памяти или используйте диспетчер памяти отладки. Иногда, однако, его очень трудно найти. Но сначала вы можете начать с режима отладки ММ.
См. в этой статье.