Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Чуба 12.02.2012.docx
Скачиваний:
4
Добавлен:
16.08.2019
Размер:
36.84 Кб
Скачать

Структурная обработка исключений

Для платформы WINDOWS все события, которые прерывают текущий ход выполнения программы (приложение) и требуют обработки, называются ИСКЛЮЧИТЕЛЬНЫМИ СИТУАЦИЯМИ.

В API Win32 существует механизм, позволяющий приложениям отвечать на неожиданное событие (например, сбой при выполнении арифметических операций, ошибка при адресации, системные ошибки) называемый структурной обработкой (SEH). Основная нагрузка по поддержке SEH ложится на компилятор, а не на ОС. Поскольку компилятор генерирует специальный код на входах и выходах блоков исключений, создает таблицы вспомогательных структур данных и представляет функции обратного вызова. Структурная обработка исключений делает возможным завершение программы из любой точки блока кода, а так же автоматически выполняет указанные программой действия и восстанавливается при ошибках. Кроме того, SEH гарантирует, что программа сможет освободить ресурсы и выполнить другие действия по очистке до того, как поток или процесс завершится, либо в соответствии с программой, либо по исключению. SEH легко добавить к имеющемуся коду, что часто упрощает логику программы.

Например, если в программе не будет обработки исключений, то такая ситуация, как разименнование нулевого указателя или деление на ноль, приведет к остановке программы.

При использовании SEH ОС дает шанс Вашему приложению определить тип, возникшей исключительной ситуации и самостоятельно ее обработать. Лучше всего предусмотреть обработку исключительной ситуации когда:

    • возникают обнаруживаемые ошибки, включая ошибки системных вызовов, и необходимо исправлять ошибку не завершая программу:

    • широко применяются указатели и существует вероятность разыменований указателей не инециалезированных должным образом.

    • Выполняется множество действий с массивами, и существует возможность, что индексы могут выйти за допустимые пределы.

    • Выполняются арифметические операции с плавающей точкой и существуют проблемы деления на ноль, неточных результатов и переполнения;

    • В коде вызывается функция, которая может породить исключительную ситуацию либо преднамеренно, либо из – за недостаточной проверки.

Обработчики исключений

Для установки контроля возникновения исключительных ситуаций в блоке кода используется два блока: _try и _except, имеющие следующий синтаксис:

_try {

блок контролируемого кода

………………………

}

_except (фильтр исключений) {

обработка исключения………….

}

Блок _try - это часть обычного кода программы и если в нем происходит исключение, ОС передает управление обработчику, т.е. блоку _except. Блок _ except всегда должен следовать за блоком _ try. Одному блоку _try соответствует только один блок _ except

Если в контролируемом блоке коде не происходит исключения, то после последнего оператора блока _try выполняется оператор, следующий за блоком _except. При возникновении исключения ОС проверят выражения, указанное в качестве фильтра. Выражение должно дать одно из трех следующих значений:

    • EXCEPTION_EXECUTE_HANDLER

    • EXCEPTION_CONTINUE_EXECUTION

    • EXCEPTION_CONTINUE_SEARCH

Первый случай является обычной ситуацией, при которой выполняется код, указанный в блоке _except. После его выполнения система считает исключение обработанным и разрешает программе продолжить работу, т.е. управление передается оператору, следующему за блоком _except .

Во втором случае система возвращает управление оператору, вызвавшему исключение, и пытается выполнить его снова.

В третьем случае система игнорирует обработчик блока _try , в котором возникло исключение, и переходит к предыдущему выполняемому блоку _try и его обработчику, который имеет выражение фильтра как в первом и во втором случаях. После окончания обработки система возвращает управление в точку вызвавшую исключение.

Часто фильтр исключений должен проанализировать ситуацию, прежде чем определить какое значение ему вернуть. Для этого можно использовать функцию GetExceptionCode, которая возвращает индикатор типа исключения. Тип исключения должен быть получен немедленно после исключения, поэтому вызвать это функцию в качестве фильтра нельзя. Выполните это возможно через созданную функцию фильтра.

Например, _except(MyFilter(GetExceptionCode())){.....}

Значение возвращаемые функцией GetExceptionCode можно разделить на несколько категорий:

    • Исключения, связанные с памятью(попытка читать или записывать по виртуальному адресу не имея соответствующих прав доступа; попытка обратится к элементу массива, индекс которого выходит за границы ;)

    • исключения, связанные с обработкой самих исключений( фильтр исключений вернул значение, отличное от трех стандартных);

    • исключения, связанные с отладкой (встретилась точка останова);

    • исключения, связанные с операциями над целыми числами (перенос или переполнение);

    • исключения, связанные с операциями над вещественными числами(неточный результат, деление на ноль, переполнение);

    • исключения, генерируемые функцией RaiseException.