Структурная
обработка исключений позволяет при возникновении ошибки в программе, обработать
эту ошибку и продолжить выполнение программы. Язык программирования С++
позволяет проводить такую обработку с помощью блоков try
и catch. Это весьма гибкий механизм обработки
исключительных ситуаций.
Его
описание можно найти в любой книге по С++. Microsoft
помимо стандартного обработчика исключительных ситуаций С++ заложила в свой
компилятор еще один механизм обработки завершения исключений. Это пара блоков:
__try __try
__finale
__except
Первый
блок предназначен для обработки завершающего блока, а второй для обработки
исключений.
В
блоке __try производится стандартное выполнение программы.
Блок __finaly выполняется всегда после блока __try. Блок __except выполняется
при возникновении исключения. Любое количество блоков __try может быть вложено один в другой.
Однако
каждый должен завершаться либо блоком finaly либо блоков except.
__try {
if (bNeedtoOut)
__leave;
return;
}
__finaly {
if (AbnormalTermination()) {}
else {}
}
__try {
//защищенный блок}
__except (
//фильтр
исключений)
{
//обработка исключений
}
Фильтр исключений – это 1 оператор. Результатом
работы этого оператора могут быть три значения 1, 0, -1.
1.
1 – EXCEPTION_EXECUTE_HANDLER
ошибка распознана. Последствия ошибки
будут ликвидированы в блоке except. Затем
программа перейдет на оператор, следующий за блоком except.
2.
0 – EXCEPTION_CONTINUE_SEARCH
Ошибка не распознана. Необходимо
перейти на следующий вверх блок except.
3.
-1 – EXCEPTION_CONTINUE_EXECUTION
Ошибка распознана и устранена.
Необходимо вернуться на ту же самую машинную команду, которая вызвала ошибку.
__try {
__try {}
__except(0) {}
}
__except (1) {}
Если такого обработчика нет, то вызвать стандартный
обработчик исключений ОС, который аварийно завершит программу.
Стек
обработчиков исключений для каждой нити свой. Текущий обработчик исключений
находится по адресу fs:0 (сегментный регистр). В ОС Windows сегментный
регистр fs не указывает на общее адресное пространство процессов. Он указывает на
небольшой блок памяти, выделяемый ОС отдельно для каждой нити. Этот блок
называется Tread Environment Block (TEB) и он не документирован. По
адресу 0 в этом блоке лежит адрес текущего обработчика исключений, который, в
свою очередь, уже относится к адресному пространству процесса.
GetExceptionInformation ();
typedef
struct {
PEXCEPTION_RECORD ExceptionRecord;
PCONTEXT ContextRecord;
}
EXCEPTION_POINTER;
typedef
struct _EXCEPTION_RECORD{
DWORD ExceptionCode;
DWORD ExceptionFlags;
struct _EXCEPTION_RECORD*
ExceptionRecord;
PVOID ExceptionAddress;
DWORD NumberParametrs;
ULOG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETRS];
} EXEPTION_RECORD, *PEXCEPTION_RECORD;
ContextRecord – содержимое контекста регистров ЦП при исключении,
который использовала данная нить.
Исключение
можно вызвать намеренно. Для этого существует функция RaiseException:
PVOID RaiseException(
DWORD ExceptionCode,
DWORD ExceptionFlags,
DWORD NumberOfArguments,
conts ULONG_PTR* lpArguments
);
Комментариев нет:
Отправить комментарий