Что происходит на уровне ОС, когда программа .net выходит из-за неперехваченного исключения?

Актуальный вопрос (ы):

Что происходит "в Windows", когда программа вылетает из неперехваченного исключения?

Есть ли функция dll, которую я могу подключить, чтобы зарегистрировать некоторую базовую информацию о сбое?

Контекст:

Я планирую написать программу, в которой будет собрана очень простая информация о любых приложениях, которые разбиваются на моем локальном компьютере. Я надеялся, что могу выполнить простой метод для регистрации некоторой информации о сбое аналогично тому, как Visual Studio создает диалоговое предложение, позволяющее вам отлаживать программу при ее сбое.

Ответ 1

Управляемые исключения реализуются с использованием обычных механизмов управления структурированными исключениями Windows. Код исключения - 0xe0434f4d. В Windows идет поиск обработчика исключений, который хочет обработать исключение. Если код не имеет активного блока try в стеке, или никакой блок блокировки не хочет поймать управляемое исключение, то последний вздох в управляемом коде будет событием AppDomain.UnhandledException.

Если это не реализовано, как переключение исключений на неуправляемую обработку, фильтр исключений, установленный с помощью SetUnhandledExceptionFilter, получает снимок. В противном случае всегда есть обработчик по умолчанию, предоставляемый Windows. Обычно запускает WER, программу отчетов об ошибках Windows. Это дает пользователю диалоговое окно для отправки сведений об исключениях в Microsoft. Не ожидайте ничего из этого.

К тому времени, когда он превысил AppDomain.UnhandledException, вся информация об управляемом исключении теряется. Нет трассировки стека, нет сообщения об исключении. Просто код исключения, который вы уже знаете, и адрес исключения, который вы не будете использовать, потому что код динамически генерируется компилятором JIT.

Обязательно залейте исключение на последнем этапе взрыва, напишите обработчик событий для AppDomain.UnhandledException. Запишите значение e.ExcdeptionObject.ToString() и убейте программу с помощью Environment.Exit(). Также будьте осторожны с событием Application.ThreadException в коде Windows Forms и событием Dispatcher.UnhandledException в коде WPF. Они представляют собой обратную остановку для исключений, которые возникают при обработке событий в потоке пользовательского интерфейса.

Ответ 2

Для собственных приложений вы можете использовать следующие функции:

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

Указатель функции, который вы передаете SetUnhandledExceptionFilter, получает структуру как входной аргумент, содержащий всю информацию об исключении (причина, регистры,...).

В моем приложении я использую SetUnhandledExceptionFilter для создания дампа приложения (используя функцию MiniDumpWriteDump из dll DBGHELP.DLL), если приложение сработает, Будьте осторожны, чтобы не делать слишком много в этой функции. Поскольку ваше приложение уже сработало, оно не гарантирует, что любая дальнейшая логика все равно будет работать (например, доступ к вашим собственным структурам данных, которые могут быть правильными, может привести к дальнейшим сбоям).

Подумайте о покупке книги "" Отладка приложений Microsoft NET 2.0" от Джона Роббинса. Я многому научился из этой книги, включая этот трюк.