The operating system uses structured exception handling to signal certain kinds of errors. A routine called by a driver can raise an exception that the driver must handle.
The system traps the following general kinds of exceptions:
Hardware-defined faults or traps, such as,
Access violations (see below)
Data-type misalignments (such as a 16-bit entity aligned on an odd-byte boundary)
Illegal and privileged instructions
Invalid lock sequences (attempting to execute an invalid sequence of instructions within an interlocked section of code)
Integer divides by zero and overflows
Floating-point divides by zero, overflows, underflows, and reserved operands
Breakpoints and single step execution (to support debuggers)
System software-defined exceptions, such as,
Guard-page violations (attempting to load or store data from or to a location within a guard page)
Page-read errors (attempting to read a page into memory and encountering a concurrent I/O error)
An access violation is an attempt to perform an operation on a page that is not permitted under the current page protection settings. Access violations occur in the following situations:
An invalid read or write operation, such as writing to a read-only page.
To access memory beyond the limit of the current program's address space (known as a length violation).
To access a page that is currently resident but dedicated to the use of a system component. For example, user-mode code is not allowed access a page that the kernel is using.
If an operation might cause an exception, the driver should enclose the operation in a try/except block. Accesses of locations in user-mode are typical causes of exceptions. For example, the ProbeForWrite routine checks that the driver can actually write to a user-mode buffer. If it cannot, the routine raises a STATUS_ACCESS_VIOLATION exception. In the following code example, the driver calls ProbeForWrite in a try/except so that it can handle the resulting exception, if one should occur.
C++
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 */
...
}
Drivers must handle any raised exceptions. An exception that is not handled causes the system to bug check. The driver that causes the exception to be raised must handle it: a lower-level driver cannot rely on a higher-level driver to handle the exception.
This module explores the use of exceptions and the exception handling process in C# console applications. Hands-on activities provide experience implementing exception handling patterns for various coding scenarios.