Что я должен знать о структурированных исключениях (SEH) в C ++? - PullRequest
42 голосов
/ 06 мая 2010

Какие важные моменты о структурированных исключениях должен знать каждый разработчик C ++?

Ответы [ 5 ]

39 голосов
/ 06 мая 2010

Они являются Win32-эквивалентом сигналов Unix и позволяют отлавливать исключения CPU, такие как нарушение доступа, недопустимые инструкции, деление на ноль.

При правильных параметрах компилятора (/ EHa для Visual C ++) исключения C ++ используют тот же механизм, что и разматывание стека работает правильно как для исключений C ++ (пользователь), так и исключений SEH (OS).

В отличие от исключений в C ++, SEH не является типизированным, но все имеют одинаковую структуру данных, в которой есть код исключения (причина) и дополнительная информация о том, какой код неисправен и что регистрирует ЦП во время сбоя. Подробнее см. GetExceptionCode и GetExceptionInformation.

Кроме того, SEH имеет обработку «первого шанса», которая позволяет регистрировать или обрабатывать исключение до того, как разматывание уничтожит все локальные переменные.

29 голосов
/ 15 октября 2010

У меня недавно была проблема, которая была косвенно вызвана SEH, особенно из-за одной особенности SEH, о которой, я думаю, должен знать каждый разработчик:

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

Наша проблема была вызвана критической секцией, которая была обернута объектом с Lock в конструкторе и Unlock в деструкторе.

У нас была тупиковая ситуация, и мы не могли понять, почему, и примерно после недели копания кода, дампов и отладки мы наконец поняли, что это потому, что было исключение, которое было обработано COM и вызвало раздел Critical. оставаться запертым. Мы изменили флаг компиляции в VS в свойствах проекта, которые говорят ему запускать деструкторы даже для SEH, и это решило проблему.

Таким образом, даже если вы не можете использовать SEH в своем коде, вы можете использовать библиотеку, которая (например, COM) и может вызвать непредвиденное поведение.

24 голосов
/ 06 мая 2010

Они должны знать, что они не являются частью стандарта C ++ - они являются изобретением Microsoft и могут использоваться на языках, отличных от C ++.

20 голосов
/ 07 мая 2010

Ускоренный курс по глубине структурной обработки исключений Win32 ™

Эта статья справка о том, как быстро освоить SEH. 13 лет спустя все еще остается лучшим.

В MSDN есть специальная тема для SEH и C ++ Различия в обработке исключений .

Некоторые вещи, которые разработчик C ++ должен знать, если обсуждается SEH:

Написание C / C ++ SEH Обработчики исключений :

__try 
{
   // guarded code
}
__except ( expression )
{
   // exception handler code
}

Это , а не Обработка исключений C ++, это специфичные для MS расширения для перехвата прямого доступа в SEH. Он работает совсем не так, как ваши обычные исключения C ++. Вам нужно хорошее понимание SEH, чтобы использовать их.

Написание C / C ++ SEH Обработчики завершения :

__try {
   // guarded code
}
__finally ( expression ) {
   // termination code
}

То же, что и с обработчиком SEH, не путайте это с семантикой исключений в C ++. Вам нужно хорошее понимание SEH.

_set_se_trasnlator: эта функция преобразует исключения SEH в исключения типа C ++ при использовании асинхронных исключений / EHa .

И, наконец, личное мнение: должен ли C ++ разработчик знать SEH? После вашего первого новичка .ecxr вы поймете, что когда дело доходит до толчка, исключения C ++ - это всего лишь иллюзия для вашего удобства. Единственное, что происходит, это SEH.

0 голосов
/ 14 июня 2019

Важным моментом является знание того, когда использовать SEH, а когда использовать стандартные исключения C ++. Сначала выберите только одну систему & ndash; Системы смешивания имеют тенденцию быть проблематичными, требующими глубокого понимания того и другого для правильной реализации. Во-вторых, на высоком уровне SEH не ограничивается C ++, в то время как стандартные исключения C ++ не ограничиваются Windows. Если это не диктует ваше решение, выбирайте стандартные исключения, если они не соответствуют требованиям (см. Другие ответы для получения дополнительной информации о возможностях SEH).

Цитата из документации Microsoft (от 13.08.2008) подтверждает этот вывод.

Структурная обработка исключений (SEH) - это расширение Microsoft до C, которое корректно обрабатывает определенные исключительные ситуации кода, такие как сбои оборудования. Хотя Windows и Microsoft C ++ поддерживают SEH, мы рекомендуем вам использовать обработку исключений C ++ в соответствии со стандартом ISO, поскольку это делает ваш код более переносимым и гибким. Тем не менее, чтобы поддерживать существующий код или для определенных видов программ, вам все равно, возможно, придется использовать SEH.

Почему автор расширения рекомендует, чтобы оно не использовалось в большинстве случаев? Предположительно, потому что расширение было написано для C, а текущий контекст - C ++. Языки схожи, поэтому перенос SEH на C ++ в качестве побочного эффекта, вероятно, был достаточно легким, даже если только «особые виды программ» действительно выиграли бы. (Или, возможно, по какой-то другой причине; возможно, портирование было начато до того, как C ++ был стандартизирован. История становится запутанной.)

...