В семействе ОС Microsoft Windows используются некоторые механизмы обработки исключений , основанные на особенностях операционной системы .
Структурированная обработка исключений
Структурированная обработка исключений Microsoft - это собственный механизм обработки исключений для Windows и технология-предшественник векторной обработки исключений (VEH). [1] В нем реализован finally
механизм, отсутствующий в стандартных исключениях C ++ (но присутствующий в большинстве императивных языков, представленных позже). SEH настраивается и обрабатывается отдельно для каждого потока выполнения .
Применение
Microsoft поддерживает SEH как метод программирования только на уровне компилятора. MS Visual C ++ компилятор имеет три нестандартных ключевые слова: __try
, __except
и __finally
- для этой цели. Другие аспекты обработки исключений поддерживаются рядом функций Win32 API , [2] например, RaiseException
для создания исключений SEH вручную.
Выполнение
IA-32
Каждый поток выполнения в версии Windows IA-32 или уровне эмуляции WoW64 для версии x86-64 имеет ссылку на недокументированный список _EXCEPTION_REGISTRATION_RECORD в начале своего информационного блока потока . Этот __try
оператор по существу вызывает функцию, определяемую компилятором EH_prolog
. Эта функция выделяет _EXCEPTION_REGISTRATION_RECORD в стеке, указывающий на функцию __except_handler3
[a] в msvcrt.dll
, [b], а затем добавляет запись в заголовок списка. В конце __try
блокаEH_epilog
вызывается определяемая компилятором функция, которая выполняет обратную операцию. Любая из этих определяемых компилятором подпрограмм может быть встроенной . Все для программиста определены __except
и __finally
блоки называются изнутри __except_handler3
. Если присутствуют блоки, определенные программистом, _EXCEPTION_REGISTRATION_RECORD, созданный с помощью EH_prolog
, расширяется несколькими дополнительными полями, используемыми __except_handler3
. [3]
В случае исключения в коде пользовательского режима операционная система [c] анализирует список _EXCEPTION_REGISTRATION_RECORD потока и последовательно вызывает каждый обработчик исключений, пока обработчик не сообщит, что он обработал исключение (по возвращаемому значению ), или список не будет исчерпан. Последним в списке всегда является тот, kernel32!UnhandledExceptionFilter
который отображает сообщение об ошибке общей защиты . [d] Затем список просматривается еще раз, давая обработчикам возможность очистить все используемые ресурсы. Наконец, выполнение возвращается в режим ядра [e], где процесс либо возобновляется, либо завершается.
Патент на этот режим SEH, US5628016, истек в 2014 году.
x86-64
SEH в 64-битной Windows не включает список обработчиков исключений во время выполнения; вместо этого он использует таблицу удаления стека ( UNWIND_INFO
), интерпретируемую системой при возникновении исключения. [4] [5] Это означает, что компилятору не нужно генерировать дополнительный код для выполнения раскрутки стека и соответствующего вызова обработчиков исключений. Он просто должен выдать информацию в виде развернутых таблиц о структуре кадра стека и указанных обработчиках исключений.
Служба поддержки
GCC 4.8+ от Mingw-w64 поддерживает использование 64-битного SEH для исключений C ++. LLVM clang поддерживает __try
как x86, так и x64. [6]
Векторная обработка исключений
Векторная обработка исключений была представлена в Windows XP . [7] Векторная обработка исключений доступна для программистов Windows, использующих такие языки, как C ++ и Visual Basic . VEH не заменяет структурированную обработку исключений (SEH), скорее VEH и SEH сосуществуют, причем обработчики VEH имеют приоритет над обработчиками SEH. [1] [7] По сравнению с SEH, VEH работает больше как сигналы Unix, доставляемые ядром . [8]
Заметки
- ^ Название различается в разных версиях среды выполнения VC.
- ^
ntdll.dll
иkernel32.dll
, как и другие программы, статически связанные со средой выполнения VC, вместо этого скомпилировали эту функцию - ^ Более конкретно,
ntdll!RtlDispatchException
системная процедура, вызываемая изntdll!KiUserExceptionDispatcher
которой, в свою очередь, вызывается изnt!KiDispatchException
функции ядра. (См. Кен Джонсон (16 ноября 2007 г.). «Каталог режима ядра NTDLL для обратных вызовов пользовательского режима, часть 2: KiUserExceptionDispatcher») . для подробностей) - ^ Сообщение можно отключить, изменив режим ошибки процесса; последний обработчик по умолчанию можно заменить на SetUnhandledExceptionFilter API
- ^
ntdll!KiUserExceptionDispatcher
вызывает либо,nt!ZwContinue
либоnt!ZwRaiseException
Рекомендации
- ^ а б «Векторная обработка исключений в Windows Server 2003 (через Интернет-архив)» . Архивировано из оригинала на 2008-01-18.
- ^ Microsoft Corp. (12 ноября 2009 г.). «Структурированные функции обработки исключений» . Библиотека MSDN . Проверено 17 ноября 2009 .
- ^ Питер Клейсснер (14 февраля 2009 г.). «Обработка исключений Windows - Питер Кляйсснер» . Архивировано из оригинального 14 октября 2013 года . Проверено 21 ноября 2009 ., Раздел структурированной обработки исключений на основе компилятора
- ^ «Исключительное поведение - обработка структурированных исключений x64» . The NT Insider.
- ^ «Обработка исключений x64» . Документация по VC ++ 2019 .
- ^ «Совместимость с MSVC» . Документация Clang 11 .
- ^ а б «Под капотом: новая векторная обработка исключений в Windows XP» . Архивировано из оригинала на 2008-09-15.
- ^ «Windows Server 2003: улучшенная информация о системе, новое ядро, отладка, безопасность и интерфейсы API» . Архивировано из оригинала на 2008-05-05.
Внешние ссылки
- Microsoft Corp. (12 ноября 2009 г.). «Структурированная обработка исключений» . Библиотека MSDN . Проверено 17 ноября 2009 .
- Мэтт Пьетрек (январь 1997 г.). «Краткий курс по глубине структурированной обработки исключений в Win32» . MSJ . 12 (1).Обратите внимание, что приведенные здесь примеры не работают как есть в современных системах Windows (после XP SP2) из-за изменений, внесенных Microsoft для решения проблем безопасности, присутствующих в раннем дизайне SEH. Примеры все еще работают в более поздних версиях Windows, если они скомпилированы с
/link /safeseh:no
. - «win32: безопасная обработка структурированных исключений» . Ясм мануал.
- Патент США 7,480,919 - Безопасные исключения
- Йоханнес Пассинг (20 мая 2008 г.). «Развлечение с низким уровнем SEH» . Охватывает неясные детали, необходимые для того, чтобы низкоуровневый код SEH (и особенно SafeSEH) работал в более современной Windows.
- Игорь Скочинский (6 марта 2006 г.). «Обращение вспять Microsoft Visual C ++, часть I: обработка исключений» . OpenRCE . Проверено 17 ноября 2009 .
- Мэтт Миллер (2 февраля 2009 г.). «Предотвращение использования структурированного обработчика исключений (SEH), перезаписываемого с помощью SEHOP» . Technet.
- Стефан Ле Бер, Дамьен Кокиль (22 декабря 2009 г.). «В обход SEHOP» (PDF) . Sysdream. Архивировано из оригинального (PDF) 07.09.2012.
- Джошуа Дж. Дрейк (10 января 2012 г.). «Старое встречается с новым: несовместимость с Microsoft Windows SafeSEH» . Статья, объясняющая, почему Windows 7 SP1 игнорирует SafeSEH для некоторых старых двоичных файлов, а Windows XP SP3 уважает его.