Главная Случайная страница Контакты | Мы поможем в написании вашей работы! | ||
|
Выражение_фильтра в операторе except вычисляется немедленно после того, как происходит исключение. Обычно это литеральная константа, вызов функции фильтра или условное выражение. Во всех случаях выражение должно возвратить одно из трех значений.
1. EXCEPTION_EXECUTE_HANDLER — система выполняет блок except. Это обычная ситуация.
2. EXCEPTION_CONTINUE_SEARCH — система игнорирует обработчик исключения и
последовательно ищет его во вложенных блоках, пока не находит.
3. EXCEPTION_CONTINUE_EXECUTION — система немедленно возвращает управление в точку, в которой произошло исключение. После некоторых исключений
продолжение невозможно, и, если программа пытается продолжить работу, не
медленно генерируется другое исключение.
Коды исключений
Блок except или выражение фильтра может определить конкретное исключение с помощью функции
DWORD GetExceptionCode (VOID)
Код исключения должен быть получен немедленно после исключения. Поэтому сама функция фильтра не может вызывать GetExceptionCode (это ограничение установлено в компиляторе). Обычно эта функция вызывается в выражении фильтра, где кодом исключения служит параметр заданной пользователем функции фильтра.
_ except (MyFilter (GetExceptionCode ())) { }
В этой ситуации функция фильтра определяет и возвращает значение выражения фильтра, которое должно быть одним из трех значений, указанных выше. Функция может определить на основе кода исключения свое возвращаемое значение; например, фильтр может передавать исключения при операциях с плавающей запятой внешнему обработчику (возвращая EXCEPTION_CONTINUE_SEARCH), а нарушение доступа к памяти обрабатывать в текущем обработчике (возвращая EXCEPTION_EXECUTE_HANDLER).
GetExceptionCode может возвращать множество различных значений кодов исключений. Все эти коды подразделяются на несколько категорий.
• Программные нарушения, например:
- EXCEPTION_ACCESS_VIOLATION — попытка читать или записывать по виртуальному адресу, к которому процесс не имеет доступа;
- EXCEPTION_DATATYPE_MISALIGNMENT — многие типы процессоров требуют, например, чтобы данные типа DWORD были выровнены по 4-байтовым границам;
- EXCEPTION_NONCONTINUABLE — значение выражения фильтра было exception_continue_execution, но после данного исключения продолжение невозможно.
• Исключения, вызываемые функциями распределения памяти, HeapAlloc и
HeapCreate, если в них используется флаг HEAP_GENERATE_EXCEPTIONS. Значение кода будет STATUS_NO_MEMORY либо EXCEPTION_ACCESS_VIOLATION.
• Определяемый пользователем код исключения, генерируемый функцией
RaiseException, которая рассматривается ниже.
• Множество разнообразных кодов по арифметическим операциям (особенно с плавающей запятой), например:
EXCEPTION_INT_DIVIDE_BY_ZERO и EXCEPTION_FLT_OVERFLOW.
• Исключения, используемые отладчиками, например EXCEPTION_BREAKPOINT и
EXCEPTION_SINGLE_STEP.
Существует также альтернативная функция, вызываемая только из выражения фильтра, которая возвращает дополнительную (в том числе зависящую от типа процессора) информацию:
LPEXCEPTION_POINTERS GetExceptionInformation (VOID)
Структура EXCEPTION_POINTERS содержит как зависимую от процессора, так и независимую информацию, сгруппированную в двух других структурах:
typedef struct _EXCEPTION_POINTERS {
PEXCEPTION_RECORD ExceptionRecord;
PCONTEXT ContextRecord;
} EXCEPTION_POINTERS;
EXCEPTION_RECORD содержит элемент для ExceptionCode, с тем же набором значений, которые возвращаются функциейGetExceptionCode. Еще один элемент
EXCEPTION_RECORD — ExceptionFlags — имеетзначение 0 или EXCEPTION_NONCONTINUABLE, что позволяет функции фильтра определить, следует ли пытаться продолжать выполнение. Другие элементы включают адрес виртуальной памяти ExceptionAddress и массив параметров ExceptionInformation. В случае EXCEPTION_ACCESS_VIOLATION первый элемент указывает, было ли это нарушение при записи (1) или при чтении (0), а второй элемент — адрес виртуальной памяти.
Второй элемент EXCEPTION_POINTERS — ContextRecord — содержит зависимую от процессора информацию. Есть разные структуры для каждого типа процессора; информацию об этом можно найти в <winnt.h>.
Дата публикования: 2015-11-01; Прочитано: 370 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!