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


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

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

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

  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++.

Дополнительные сведения о структурированной обработке исключений см. в пакете SDK Для Microsoft Windows и документации по Visual Studio.