Как отладить сбой, который происходит только при завершении работы приложения? (Delphi) - PullRequest
13 голосов
/ 03 марта 2011

Итак, после некоторых недавних изменений мы обнаружили, что одно из наших самых старых приложений иногда падает при завершении работы. Это проявляется либо в форме сообщений «Runtime error 216», либо в сообщении Windows Error Reporting о том, что приложение перестало работать. Приложение уже отправляет OutputDebugString -мессий на каждом шагу, и AFAICT весь наш собственный код выполняется правильно до завершения. Все деструкторы вызываются так же, как и все разделы финализации и деструкторы классов, ни один из которых не вызывает никаких исключений.

Кроме того, ни в madExcept, ни в режиме Full Debug FastMM4, похоже, не на что жаловаться (хотя это может быть ложным выводом, потому что сбой может произойти даже до запуска собственного кода завершения этих компонентов).

Итак, что бы вы сделали? С чего бы начать?


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

Ответы [ 6 ]

12 голосов
/ 03 марта 2011

Ошибка 216 во время выполнения означает, что у вас Av (нарушение прав доступа), и SysUtils уже прекратил переводить эти ошибки в исключения.

Первая попытка: Сборка с отладочными DCU и поиск в системе единиц, где возникает ошибка, установите точку останова там. надеюсь, вы сможете отловить его в отладчике и работать оттуда.

Возможно, у вас есть ошибка памяти (висячий указатель, нулевая ссылка и т. Д. И т. Д. Использование строковой константы s в уже завершенном модуле), и лучший способ - проверить финализацию после завершения sysutils. Вы можете сделать это, создавая WITH debug dcu, устанавливая точку останова для завершения в sysutils и начав пошаговое выполнение кода, пока не произойдет ошибка.

5 голосов
/ 03 марта 2011

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

3 голосов
/ 03 марта 2011

Что ж, Ошибка времени выполнения 216 - это проблема с памятью ( Нарушение доступа ), похоже, вы ссылаетесь на некоторый Объект, который не существует в этот момент времени.

Emarcadero пишет:

Приложения, использующие класс SysUtils, отображают большинство ошибок времени выполнения в исключения, которые позволяют вашему приложению устранить ошибку без завершения

Вы пытались установить точку взлома в разделе финализации Sysutils?

Я бы попробовал его с Allocation / Memory Profiler, он не уверен, что вы найдете строку кода ошибки, но это может показать вам некоторые части вашего кода, где возникают проблемы с памятью.

2 голосов
/ 04 марта 2011

Как и другие говорили: 216 означает AV после завершения работы SysUtils.Обычно единственное, что отключается после SysUtils (и есть шанс поднять AV) - это системный блок.В частности: менеджер памяти.

Итак, ошибка 216 во время выполнения при выключении обычно означает повреждение памяти ошибка в вашем приложении.

Это может быть очень легко устранить - простовключите режим полной отладки в диспетчере памяти или используйте диспетчер памяти отладки.Иногда, однако, это может быть очень трудно найти.Но сначала вы можете начать с режима отладки MM.

См. эту статью .

2 голосов
/ 03 марта 2011

«Ошибка выполнения 216» происходит от самой Windows, а не от обработчика исключений Delphi. Я обнаружил, что это вызвано кодом, который выполняется в разделах инициализации и финализации модулей, которые выполняются до того, как включается обработчик исключений Delphi. В частности. COM-объекты, которые необходимо выгрузить с помощью кода завершения, выполняющегося после завершения работы Delphi App, вызовут эту и подобные ошибки. Так что проверь это.

MNG

2 голосов
/ 03 марта 2011

Вероятно, у вас проблема с указателем. Некоторое событие или метод пытается запустить объект, который больше не существует.

...