Обработка исключений в WindowsC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Обработка исключений в Windows

Сообщение Anonymous »

Windows предоставляет следующие платформы обработки исключений:
  • Структурированная обработка исключений (SEH)
  • Векторная обработка исключений ( VEH)
SEH — это просто версия C++ try-catch для Windows, и сама Microsoft предложила использовать C++ try-catch блоки. Я не хочу везде использовать try-catch, а хочу иметь один обработчик исключений "catch-all".
Это приводит к VEH, который, в отличие от SEH, не является конструкция обработки исключений на основе фреймов, т. е. для всего процесса, а не только для каждого потока.
Но есть еще один метод — UnHandledExceptionFilter. На самом деле это часть SEH. В Windows часть __Exception содержит выражение фильтра (подробно описанное здесь), которое решает, следует ли вызывать обработчик исключений (который следует за предложением __Exception) или передавать его другим обработчикам исключений в стеке. .

Код: Выделить всё

__try {
// guarded code
}
__except ( /* filter expression */ ) {
// the exception handler (as Windows calls it)
}
Теперь, если ни один из обработчиков исключений не совпадает, вызывается обработчик исключений, установленный с помощью метода SetUnhandledExceptionFilter. На мой взгляд, это похоже на обработчик исключений, не связанных с кадрами (например, VEH), но на самом деле он основан на кадрах, поскольку это последний обработчик исключений, который перехватывает все исключения, которые не были перехвачены предложением __Exception SEH. В моем случае, если я не пишу никаких блоков try-Exception, вызывается метод, который я установил с помощью SetUnhandledExceptionFilter, что имеет смысл, поскольку обработчиков исключений было 0, поэтому по умолчанию все исключения считается «нефильтрованным» и запускает UnhandledExceptionFilter.
Теперь я не уверен, какой из них использовать — VEH или UnhandledExceptionFilter. VEH не основан на кадрах и вызывается перед UnhandledExceptionFilter. Оба могут обрабатывать все «неперехваченные исключения».
Далее, после перехвата исключения (с помощью VEH или UnhandledExceptionFilter) в рабочем потоке (потоках, созданных приложением), какова ожидание? Может ли приложение продолжить работу?

Вот пример сценария: если произошло деление на ноль или нарушение прав доступа из-за ошибки в рабочем потоке, я бы хотел подать сигнал основному потоку и убить рабочий поток. нить. Основной поток завершает все мои структуры, показывает пользователю окно сообщения с двумя опциями: «Перезапустить» и «Выйти», и если пользователь выбирает «Перезапустить», снова инициализируйте все мои структуры. Это возможно, но рекомендуется ли это?

Что касается возвращаемых значений, в документации VEH сказано:

Чтобы вернуть управление в точку, в которой произошло исключение, верните
EXCEPTION_CONTINUE_EXECUTION (0xffffffff). Чтобы продолжить поиск в обработчике
, верните EXCEPTION_CONTINUE_SEARCH (0x0).

и в документации UnhandledExceptionFilter говорится, что есть следующие возвращаемые значения: EXCEPTION_CONTINUE_SEARCH и EXCEPTION_EXECUTE_HANDLER, отличные от VEH.
Что делать, если исключение возникает в основном нить? Затем в основном потоке вызываются VEH и UnhandledExceptionFilter. Я не могу убить поток в этом сценарии. Какова рекомендация Window?
Есть еще одно сообщение stackoverflow, в котором говорится, что VEH не заменяет UnhandledExceptionFilter и его следует использовать только в качестве диагностического инструмента, но я не понял .
По сути, я хочу знать, каков рекомендуемый Windows способ аккуратной обработки исключений в приложении Windows. Подводя итог моим вопросам следующим образом:
  • VEH против UnhandledExceptionFilter – какой из них использовать и почему? Каковы рекомендации Windows?
  • После обнаружения исключения (в обоих случаях – основного или рабочего потока) как должно вести себя приложение?
Примечание: я понимаю, что уничтожение потока не является хорошей практикой и имеет некоторые последствия (одним из которых является то, что стек не раскручивается), но это не основная тема этой статьи. Если я уничтожу поток, мне не придется иметь дело с рекурсивными исключениями, и я потенциально смогу перезапустить приложение в том же пространстве процесса.
Обновление 1: я не могу использовать try-catch
Обновление 1: я не могу использовать try-catch по нескольким причинам - он работает, только если вы генерируете исключение (здесь я могу ошибаться)... Он не улавливает деление на ноль (как показано здесь). Я никогда не использовал try-catch, поэтому не разбираюсь в нем, но в моем проекте рекомендуется никогда не использовать try-catch, за исключением стороннего API, который выдает , используется. Все функции отмечены как noException. Есть и другие причины, но это отвлечение от темы.

Подробнее здесь: https://stackoverflow.com/questions/791 ... in-windows
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»