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

Операционная система использует структурированную обработку исключений для сигнализации определенных типов ошибок. Подпрограмма, вызываемая драйвером, может вызвать исключение, которое должен обработать драйвер.

Система перехватывает следующие общие виды исключений:

  1. Определяемые оборудованием ошибки или ловушки, например,

    • Нарушения доступа (см. ниже)
    • Несоответствия типов данных (например, 16-битовая сущность, выровненная по нечетной границе)
    • Недопустимые и привилегированные инструкции
    • Недопустимые последовательности блокировки (попытка выполнить недопустимую последовательность инструкций в заблокированном разделе кода)
    • Целое число делится на ноль и переполнение
    • Операции с плавающей запятой делятся на ноль, переполнения, недополуки и зарезервированные операнды
    • Точки останова и одношаговая реализация (для поддержки отладчиков)
  2. Системные программно-определяемые исключения, такие как

    • Нарушения страницы защиты (попытка загрузки или хранения данных из или в расположении на странице защиты)
    • Ошибки чтения страницы (попытка чтения страницы в памяти и одновременная ошибка ввода-вывода)

Нарушение доступа — это попытка выполнить операцию на странице, которая не разрешена в текущих параметрах защиты страницы. Нарушения доступа происходят в следующих ситуациях:

  • Недопустимая операция чтения или записи, например запись на страницу, доступную только для чтения.

  • Доступ к памяти за пределами адресного пространства текущей программы (это называется нарушением длины).

  • Доступ к странице, которая в настоящее время является резидентной, но выделенной для использования системного компонента. Например, коду пользовательского режима не разрешен доступ к странице, используемой ядром.

Если операция может вызвать исключение, драйвер должен заключить операцию в блок 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.