예외 처리

운영 체제는 구조적 예외 처리를 사용하여 특정 종류의 오류를 신호로 보냅니다. 드라이버에서 호출하는 루틴은 드라이버가 처리해야 하는 예외를 발생시키는 것입니다.

시스템은 다음과 같은 일반적인 종류의 예외를 트래핑합니다.

  1. 하드웨어 정의 오류 또는 트랩(예: )

    • 액세스 위반(아래 참조)
    • 데이터 형식 오차(예: 홀수 바이트 경계에 정렬된 16비트 엔터티)
    • 불법 및 권한 있는 지침
    • 잘못된 잠금 시퀀스(코드의 연동된 섹션 내에서 잘못된 명령 시퀀스를 실행하려고 시도)
    • 정수는 0과 오버플로로 나눕니다.
    • 부동 소수점은 0, 오버플로, 언더플로 및 예약 피연산자를 나눕니다.
    • 중단점 및 단일 단계 실행(디버거 지원)
  2. 시스템 소프트웨어 정의 예외(예: )

    • 가드 페이지 위반(가드 페이지 내의 위치로 데이터를 로드하거나 저장하려고 시도)
    • 페이지 읽기 오류(메모리로 페이지를 읽으려고 시도하고 동시 I/O 오류가 발생함)

액세스 위반은 현재 페이지 보호 설정에서 허용되지 않는 페이지에서 작업을 수행하려는 시도입니다. 액세스 위반은 다음과 같은 경우에 발생합니다.

  • 읽기 전용 페이지에 쓰는 것과 같은 잘못된 읽기 또는 쓰기 작업입니다.

  • 현재 프로그램의 주소 공간 제한을 초과하여 메모리에 액세스하려면(길이 위반이라고 함)

  • 현재 상주하지만 시스템 구성 요소 사용 전용인 페이지에 액세스합니다. 예를 들어 사용자 모드 코드는 커널에서 사용하는 페이지에 액세스할 수 없습니다.

작업으로 인해 예외가 발생할 수 있는 경우 드라이버는 try/except 블록에 작업을 묶어야 합니다. 사용자 모드의 위치 액세스는 예외의 일반적인 원인입니다. 예를 들어 ProbeForWrite 루틴은 드라이버가 실제로 사용자 모드 버퍼에 쓸 수 있는지 확인합니다. 이렇게 할 수 없는 경우 루틴은 STATUS_ACCESS_VIOLATION 예외를 발생합니다. 다음 코드 예제에서 드라이버는 try/except에서 ProbeForWrite를 호출하므로 결과 예외가 발생할 경우 처리할 수 있습니다.

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 설명서를 참조하세요.