Механизмы обработки исключительных ситуаций

Автор работы: Пользователь скрыл имя, 21 Мая 2013 в 00:23, курс лекций

Описание работы

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

Файлы: 1 файл

08. Механизмы обработки исключительных ситуаций.docx

— 67.11 Кб (Скачать файл)

Лекция 8



 

Механизмы обработки  исключительных ситуаций

 

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

Понятие «исключительная  ситуация» не эквивалентно понятию  «разрушительное событие». Исключительную ситуацию правильнее рассматривать как проблему, требующую разрешения с целью обеспечения «робастности»1 программы. Задача программиста – решить, какие события следует считать исключительными в данной программе, и написать программный код для обработки таких событий.

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

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

Исключения (англ. exception) синхронны и могут возникнуть только при исполнении определённых инструкций программы. Например, ошибка чтения файла и нехватка памяти являются типичными синхронными исключениями, поскольку возникают они только при выполнении операции чтения из файла и операции выделения памяти, соответственно.

Возникновение некоторых  событий может вызывать как исключения, так и сигналы. Например, выполнение инструкции целочисленного деления  на нуль обычно вызывает исключение, однако на некоторых программно-аппаратных платформах, за счёт конвейеризации вычислений процессором, эта ошибка может вызвать сигнал.

Специфическими исключительными  ситуациями являются прерывания. Прерыванием (англ. interrupt) называется сигнал-заказ от некоторого источника (периферийного устройства, процессора или исполняющейся программы), на выполнение процессором немедленных действий при наступлении некоторого события (например, при нажатии комбинации клавищ Ctrl+Break). При этом выполнение текущей последовательности команд процессора немедленно приостанавливается, и управление передаётся программе - обработчику прерывания. Реагируя на сигнал, обработчик прерывания обрабатывает его средствами ОС, после чего возвращает управление в прерванный код программы.

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

 

 

8.1   Механизм обработки сигналов

 

Непредвиденное возникновение  асинхронного события (сигнала), может привести к преждевременному аварийному завершению программы. Вот лишь некоторые из непредвиденных событий: прерывания, недопустимые программные инструкции, нарушение сегментации памяти, запрос на завершение от операционной системы, исключительные ситуации при работе с вещественными данными (деление на нуль или переполнение порядка).

Механизм обработки сигналов языка С++ обеспечивает возможность их генерации с помощью функции raise и перехвата с помощью функции signal. Вызов этих функций оформляется согласно следующим правилам:

 

генерация сигнала ::= raise, «(», номер сигнала, «);»;

перехват сигнала ::=

   signal, «(», номер сигнала, «,», указатель на функцию обработки сигнала, «);»;

 

Стандартными являются сигналы, описанные в заголовочном файле signal.h (таблица 8.1).

 

                                                                                                                                        Таблица 8.1

Сигнал

Причина

SIGABRT

аварийное завершение программы, например, вследствие вызова функции  abort

SIGFPE

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

SIGILL

попытка выполнения недопустимой программной инструкции

SIGINT

получение интерактивного сигнала  прерывания, например, при нажатии  клавиш Ctrl+Break

SIGSEGV

некорректный доступ к  памяти

SIGTERM

запрос на завершение, направленный программе


 

Перехват и обработку  сигналов можно использовать для  предотвращения непредвиденного прерывания выполнения программы.

 

Пример:

 

void signalHandler (int Sig) {

  // на монитор будет  выведена строка «Abnormal program termination:22»

  cerr << "Abnormal program termination:" << Sig << endl;

  getch ( );

}

 

int main(int argc, char* argv[ ])

{

  signal (SIGABRT, signalHandler); // перехват синала SIGABRT

  raise (SIGABRT); // генерация синала SIGABRT

  return 0;

}

 

 

 

 

 

 

8.2   Механизмы  обработки исключений

 

Исключение в С++представляет собой временную сущность (данное, экземпляр класса или функцию), которая представляет возникшую в программе исключительную ситуацию.

Исключение может генерироваться программно с помощью инструкции throw согласно правилу:

 

временный объект ::=

   данное целого типа | постоянная строкового типа | объект класса;

программная генерация  исключения ::=

   throw, [ временный объект, { «,», временный объект } ], «;»;

 

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

В языке С++существует базовый класс Exception, который представляет предопределенные исключения. Идентификаторы таких исключений начинаются с символа ‘E’ с последующим кратким описательным именем. В таблице 8.2 приведены некоторые распространенные исключения, принадлежащие классу Exception.

                                                                                                       

                                                                                                                         Таблица 8.2

Исключение

Причина

EOutOfMemory

недостаточно памяти

EDivByZero

деление на нуль целых чисел

EZeroDivide

деление на нуль действительных чисел

EIntOverflow

целочисленное переполнение

EOverflow

переполнение при операции с плавающей точкой

ERangeError

ошибка выхода за границы

EMathError

ошибка выполнения математических функций

EInvalidOp

неверная операция с плавающей  точкой

EInvalidPointer

неверная операция с указателем

EInvalidCast

неверное преобразование типов

EConvertError

неверное преобразование типов функциями

EStackOverflow

переполнение стека

EInOutError

ошибка ввода / вывода

EFileNotFound

файл не найден

EInvalidFileName

неверное имя файла

EAccessViolation

неверный доступ к памяти (например, нулевой указатель)

EEndOfFile

выход за пределы файла

EDiskFull

переполнение диска

EControlC

нажатие клавиш <Ctrl>+<C> в консольном приложении


 

Наиболее интересным свойством  класса Exception с практической точки зрения является свойство Message, которое содержит текстовую строку объявления исключения. Для определения имени класса, возбудившего исключение, часто применяется метод:

 

ClassName (char* ClassName ( ))

 

, который возвращает текстовую  строку - идентификатор такого класса.

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

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

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

  1. Обработка исключения с возвратом в программу подразумевает, что обработчик исключения ликвидирует возникшую проблему и приводит программу в состояние, когда она может работать дальше по основному алгоритму. В этом случае после выполнения кода обработчика управление передаётся в точку возникновения исключения, и выполнение программы продолжается.
  2. Обработка исключения без возврата в программу заключается в том, что после выполнения кода обработчика исключения управление передаётся в некоторое, заранее заданное место программы, и с него продолжается исполнение программного кода.

Существует  два варианта реализации обработчика  исключений: структурный и неструктурный2.

 

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

 

Структурный обработчик исключений реализуется в виде «обёрточной» синтаксической конструкции, охватывающей блок контролируемого кода (который может вызвать исключение), и один или нескольких блоков обработки исключений.

Структурный обработчик исключений описывается согласно правилам:

 

исключение3 ::=

  (тип временного объекта | «…»), &, [ «», идентификатор ];

структурный обработчик исключений ::=

   try, «{», блок контролируемого кода, «}»,

   [ { catch, «(», исключение, «)», «{», код обработчика исключения, «}» } ], «;»;

 

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

 

Примеры:

 

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

     try {

       . . .

       throw "This is a test"; // генерация исключения, заданного постоянной строкового типа

       . . .

     } catch (const char* p) { // перехват исключения, заданного постоянной строкового типа

          cout << p; // обработка исключения

       }

 

  1.  // пример генерации и обработки исключения, заданного классом TOverflow

 

      class TOverflow {

   public:

     int X;

     TOverflow(int x) {

       X = x;

       // вывод сообщения о возникновении исключения 

       cout << X << " (event has brought about overflow!)" << endl;

       X = 0; // значение по умолчанию

     }

};

 

int main(int argc, char* argv[ ])

{ int X, A;

 

  cout << "A=";    cin >> A;

 

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

   if (A < 32767) X = A;

   else throw TOverflow (A); // генерация исключения, заданного классом TOverflow

  }   catch (TOverflow& overflowObject) {      

          // перехват исключения, заданного классом TOverflow

          X = overflowObject.X; // приваивание переменной значения по умолчанию

      }

  cout << "X = " << X << endl; // вывод результирующего значения переменной

  return 0;

}

 

  1. // пример использования предопределенных исключений класса Exception

int X = 5, Y;

 

try {

  Y = X / 0;

  cout << "Y=" << Y << endl;

} catch (EDivByZero& e) {

    cout << e.Message.c_str ( ); // будет выведено сообщение «EDivByZero»

  }

 

Если в инструкции catch объявление исключения представлена эллипсисом (символом «…»), то эта инструкция перехватывает все возможные исключения.

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

Иногда бывает желательно, чтобы при возникновении  исключения обработчик выполнил какие-то действия, но исключение продолжило бы обрабатываться на более высоком уровне (обычно так бывает, когда обработчик данного блока не полностью обрабатывает исключение, а лишь частично). В таких случаях в обработчике исключений повторно генерируется уже обработанное исключение инструкцией throw без параметров.

 

 

8.2.2   Механизм структурный обработчик исключений SEH

 

Механизм структурной обработки исключений SEH4 поддерживается ОС Windows и несколько отличается от стандартной обработки исключений в С++5. Следует избегать одновременного использования механизмов обработки исключений С++ и SEH из-за возможных их конфликтов: механизм структурной обработки исключений SEH обрабатывает исключения на низком уровне ОС, а механизм структурной обработки исключений С++ - обрабатывает исключения на высоком (программном) уровне.

Информация о работе Механизмы обработки исключительных ситуаций