운영 체제는 구조적 예외 처리를 사용하여 특정 종류의 오류를 알릴 수 있습니다. 드라이버에서 호출하는 루틴은 드라이버가 처리해야 하는 예외를 발생시키는 것입니다.
시스템은 다음과 같은 일반적인 종류의 예외를 트래핑합니다.
하드웨어에 의해 정의된 오류 또는 트랩, 예:
- 액세스 위반(아래 참조)
- 데이터 형식 잘못된 정렬(예: 홀수 바이트 경계에 정렬된 16비트 엔터티)
- 불법 및 권한 있는 지침
- 잘못된 잠금 시퀀스(코드의 연동 섹션 내에서 잘못된 명령 시퀀스를 실행하려고 시도)
- 정수는 0과 오버플로로 나눕니다.
- 부동 소수점 연산에서 0으로 나누기, 용량 초과, 용량 부족, 및 예약된 피연산자
- 중단점 및 단일 단계 실행(디버거 지원)
시스템 소프트웨어 정의 예외(예:
- 가드 페이지 위반(가드 페이지 내의 위치로 데이터를 로드하거나 저장하려고 시도함)
- 페이지 읽기 오류(메모리로 페이지를 읽으려고 시도하고 동시 I/O 오류가 발생함)
액세스 위반 현재 페이지 보호 설정에서 허용되지 않는 페이지에서 작업을 수행하려는 시도입니다. 액세스 위반은 다음과 같은 경우에 발생합니다.
읽기 전용 페이지에 쓰는 것과 같은 잘못된 읽기 또는 쓰기 작업입니다.
현재 프로그램의 주소 공간 제한을 초과하여 메모리에 액세스하려면(길이 위반이라고 함)
현재 상주하지만 시스템 구성 요소 사용을 전용으로 사용하는 페이지에 액세스합니다. 예를 들어 사용자 모드 코드는 커널에서 사용하는 페이지에 액세스할 수 없습니다.
작업으로 인해 예외가 발생할 수 있는 경우 드라이버는 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 설명서를 참조하세요.