Поделиться через


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

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

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

  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.