Обработка исключений
Операционная система использует структурированную обработку исключений для сигнализации определенных типов ошибок. Подпрограмма, вызываемая драйвером, может вызвать исключение, которое должен обработать драйвер.
Система перехватывает следующие общие виды исключений:
Определяемые оборудованием ошибки или ловушки, например,
- Нарушения доступа (см. ниже)
- Несоответствия типов данных (например, 16-битовая сущность, выровненная по нечетной границе)
- Недопустимые и привилегированные инструкции
- Недопустимые последовательности блокировки (попытка выполнить недопустимую последовательность инструкций в заблокированном разделе кода)
- Целое число делится на ноль и переполнение
- Операции с плавающей запятой делятся на ноль, переполнения, недополуки и зарезервированные операнды
- Точки останова и одношаговая реализация (для поддержки отладчиков)
Системные программно-определяемые исключения, такие как
- Нарушения страницы защиты (попытка загрузки или хранения данных из или в расположении на странице защиты)
- Ошибки чтения страницы (попытка чтения страницы в памяти и одновременная ошибка ввода-вывода)
Нарушение доступа — это попытка выполнить операцию на странице, которая не разрешена в текущих параметрах защиты страницы. Нарушения доступа происходят в следующих ситуациях:
Недопустимая операция чтения или записи, например запись на страницу, доступную только для чтения.
Доступ к памяти за пределами адресного пространства текущей программы (это называется нарушением длины).
Доступ к странице, которая в настоящее время является резидентной, но выделенной для использования системного компонента. Например, коду пользовательского режима не разрешен доступ к странице, используемой ядром.
Если операция может вызвать исключение, драйвер должен заключить операцию в блок try/except . Доступ к расположениям в пользовательском режиме является типичными причинами исключений. Например, подпрограмма ProbeForWrite проверяет, может ли драйвер на самом деле выполнять запись в буфер пользовательского режима. Если это невозможно, подпрограмма создает STATUS_ACCESS_VIOLATION исключение. В следующем примере кода драйвер вызывает ProbeForWrite в try/except , чтобы обработать результирующее исключение, если оно должно возникнуть.
try {
...
ProbeForWrite(Buffer, BufferSize, BufferAlignment);
/* Note that any access (not just the probe, which must come first,
* by the way) to Buffer must also be within a try-except.
*/
...
} except (EXCEPTION_EXECUTE_HANDLER) {
/* Error handling code */
...
}
Драйверы должны обрабатывать все возникающие исключения. Исключение, которое не обрабатывается, приводит к ошибке системы проверка. Драйвер, вызывающий исключение, должен обрабатывать его: драйвер более низкого уровня не может полагаться на драйвер более высокого уровня для обработки исключения.
Драйверы могут вызывать исключение напрямую с помощью подпрограмм ExRaiseAccessViolation, ExRaiseDatatypeMisalignment или ExRaiseStatus . Драйвер должен обрабатывать все исключения, создаваемые этими подпрограммами.
Ниже приведен неполный список подпрограмм, которые, по крайней мере в определенных ситуациях, могут вызывать исключение:
Доступ к памяти к буферам пользовательского режима также может привести к нарушениям доступа. Дополнительные сведения см. в разделе Ошибки при ссылке на адреса User-Space.
Обратите внимание, что структурированная обработка исключений отличается от исключений C++. Ядро не поддерживает исключения C++.
Дополнительные сведения о структурированной обработке исключений см. в Microsoft Windows SDK и документации по Visual Studio.