Пример: использование функции фильтра

Пример: использование функции фильтра

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

Блок __finally восстанавливает состояние маски FP-исключений. Совершенно очевидно, что восстановление состояния маски в данном случае, когда процесс уже должен завершаться, особого значения не имеет, но эта методика пригодится нам впоследствии, когда мы будем использовать ее на стадии завершения выполнения потока. Вообще говоря, процесс должен восстанавливать и системные ресурсы, например, удалять временные файлы, освобождать ресурсы синхронизации (глава 8) и отменять блокирование файлов (главы 3 и 6). Функция фильтра представлена в программе 4.4.

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

Программа 4.3. Exception: обработка исключений и завершения выполнения

#include "EvryThng.h"

#include <float.h>

DWORD Filter(LPEXCEPTION_POINTERS, LPDWORD);

double x = 1.0, у = 0.0;

int _tmain(int argc, LPTSTR argv[]) {

 DWORD ECatgry, i = 0, ix, iy = 0;

 LPDWORD pNull = NULL;

 BOOL Done = FALSE;

 DWORD FPOld, FPNew;

 FPOld = _controlfp(0, 0); /* Сохранить старую управляющую маску. */

 /* Разрешить FP-исключения. */

 FPNew = FPOld & ~(EM_OVERFLOW | EM_UNDERFLOW | EM_INEXACT | EM_ZERODIVIDE | EM_DENORMAL | EM_INVALID);

 _controlfp(FPNew, MCW_EM);

 while (!Done) _try { /* Блок try-finally. */

  _tprintf(_T("Введите тип исключения: "));

  _tprintf(_T(" 1: Mem, 2: Int, 3: Flt 4: User 5: __leave "));

  _tscanf(_T("%d"), &i);

  __try { /* Блок try-except. */

   switch (i) {

   case 1: /* Исключение при обращении к памяти. */

    ix = *pNull;

    *pNull = 5;

    break;

   case 2: /* Исключение при выполнении арифметических операций над целыми числами. */

    ix = ix / iy;

    break;

   case 3: /* FP-исключение. */

    x = x / у;

    _tprintf(_T("x = %20e "), x);

    break;

   case 4: /* Пользовательское исключение. */

    ReportException(_T("Пользовательское исключение"), 1);

    break;

   case 5: /* Использовать оператор _leave для завершения выполнения.*/

    __leave;

   default:

    Done = TRUE;

   }

  } /* Конец внутреннего блока __try. */

  __except(Filter(GetExceptionInformation(), &ECatgry)) {

   switch(ECatgry) {

   case 0:

    _tprintf(_T("Неизвестное исключение "));

    break;

   case 1:

    _tprintf(_T("Исключение при обращении к памяти "));

    continue;

   case 2:

    _tprintf(_T("Исключение при выполнении арифметических операций над целыми числами "));

    break;

   case 3:

    _tprintf(_Т("FР-исключение "));

    _clearfp();

    break;

   case 10:

    _tprintf(_T("Пользовательское исключение "));

    break;

   default:

    _tprintf(_T("Неизвестное исключение "));

    break;

   } /* Конец оператора switch. */

   _tprintf(_Т("Конец обработчика "));

  }

  /* Конец блока try-except. */

 } /* Конец цикла while – ниже находится обработчик завершения. */

 __finally { /* Это часть цикла while. */

  _tprintf(_T("Аварийное завершение?: %d "),

  AbnormalTermination());

 }

 _controlfp(FPOld, 0xFFFFFFFF); /* Восстановить старую FP-маску.*/

 return 0;

}

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

Программа 4.4. Функция Filter

static DWORD Filter(LPEXCEPTION_POINTERS pExP, LPDWORD ECatgry)

/* Классификация исключений и выбор соответствующего действия. */

{

 DWORD ExCode, ReadWrite, VirtAddr;

 ExCode = pExP->ExceptionRecord->ExceptionCode;

 _tprintf(_T("Filter. ExCode:. %x "), ExCode);

 if ((0x20000000 & ExCode) != 0) { /* Пользовательское исключение. */

  *ECatgry =10;

  return EXCEPTION_EXECUTE_HANDLER;

 }

 switch (ExCode) {

 case EXCEPTION_ACCESS_VIOLATION:

  ReadWrite = /* Операция чтения или записи? */

   pExP->ExceptionRecord->ExceptionInformation[0];

  VirtAddr = /* Адрес сбоя в виртуальный памяти. */

   pExP->ExceptionRecord->ExceptionInformation [1];

  _tprintf(_T("Нарушение доступа. Чтение/запись: %d. Адрес: %х "), ReadWrite, VirtAddr);

  *ECatgry = 1;

  return EXCEPTION_EXECUTE_HANDLER;

 case EXCEPTION_INT_DIVIDE_BY_ZERO:

 case EXCEPTION_INT_OVERFLOW:

  *ECatgry = 2;

  return EXCEPTION_EXECUTE_HANDLER;

 case EXCEPTION_FLT_DIVIDE_BY_ZERO:

 case EXCEPTION_FLT_OVERFLOW:

  _tprintf(_T("FP-исключение — слишком большое значение. "));

  *ECatgry = 3;

  _clearfp();

  return (DWORD)EXCEPTION_EXECUTE_HANDLER;

 default:

  *ECatgry = 0;

  return EXCEPTION_CONTINUE_SEARCH;

 }

}

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

Использование функции SignalObjectAndWait

Из книги Системное программирование в среде Windows автора Харт Джонсон М

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


Использование встроенных форматов для функции Format

Из книги VBA для чайников автора Каммингс Стив

Использование встроенных форматов для функции Format В табл. 11.2 приводятся именованные встроенные форматы для данных различных типов в VBA. Используйте их как аргумент в функции Format. He забудьте при этом заключить в кавычки имя выбранного вами формата (из первого столбца


1.8.6. Использование функции Spotlight в системных настройках

Из книги Самоучитель работы на Macintosh автора Скрылина Софья

1.8.6. Использование функции Spotlight в системных настройках Утилита Системные настройки (System Preferences) — это самый главный пульт управления настройками системы, заданных по умолчанию. Помните, к нему мы обращались для настройки: панели Dock (мини-утилита Dock), элементов окна


Использование функции автоотчета

Из книги Access 2002: Самоучитель автора Дубнов Павел Юрьевич

Использование функции автоотчета Отчет, созданный таким образом, будет отображать все поля и записи базовой таблицы или запроса.В разделе Объекты окна базы данных щелкните сначала по кнопке а затем по кнопке Новый. На экране появится окно Новый отчет – рис. 5.1. Рис.


Простой пример функции io_read()

Из книги Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform автора Кёртен Роб

Простой пример функции io_read() Чтобы проиллюстрировать, как ваш администратор ресурса мог бы возвращать клиенту данные, рассмотрим простейший администратор ресурса, который всегда возвращает одну и ту же строковую константу «Здравствуй, мир! ». Даже в таком простом случае


Простой пример функции io_write()

Из книги Искусство программирования на языке сценариев командной оболочки автора Купер Мендель

Простой пример функции io_write() Это был простой пример функции io_read(); давайте теперь перейдем к функции io_write(). Основной камень преткновения, связанный с io_write(), — получить доступ к данным. Поскольку библиотека администратора ресурсов считывает лишь незначительную часть


Простой пример функции io_devctl()

Из книги C++ для начинающих автора Липпман Стенли

Простой пример функции io_devctl() Клиентский вызов devctl() формально определен так:#include <sys/types.h>#include <unistd.h>#include <devctl.h>int devctl(int fd, int dcmd, void *dev_data_ptr, size_t nbytes, int *dev_info_ptr);Прежде чем рассматривать эту функцию с позиций администратора ресурсов, надо сначала понять, что это за


Пример функции io_devctl() , имеющей дело с данными

Из книги UNIX: разработка сетевых приложений автора Стивенс Уильям Ричард

Пример функции io_devctl(), имеющей дело с данными В предыдущем примере io_devctl() мы подняли вопрос о том, как устанавливать произвольные значения частоты дискретизации, Очевидно, создание большого количества констант DCMD_AUDIO_SET_SAMPLE_RATE_* было бы не самым оптимальным решением — у


Пример 17-8. Встроенные документы и функции

Из книги автора

Пример 17-8. Встроенные документы и функции #!/bin/bash# here-function.shGetPersonalData (){ read firstname read lastname read address read city read state read zipcode} # Это немного напоминает интерактивную функцию, но...# Передать ввод в функцию.GetPersonalData <<RECORD001BozoBozeman2726 Nondescript Dr.BaltimoreMD21226RECORD001echoecho "$firstname $lastname"echo "$address"echo "$city,


10.11. Пример шаблона функции

Из книги автора

10.11. Пример шаблона функции В этом разделе приводится пример, показывающий, как можно определять и использовать шаблоны функций. Здесь определяется шаблон sort(), который затем применяется для сортировки элементов массива. Сам массив представлен шаблоном класса Array (см.


Простой пример использования функции select

Из книги автора

Простой пример использования функции select Теперь мы переделаем код нашего получателя внеполосных данных и вместо сигнала SIGURG будем использовать функцию select. В листинге 24.3 показана принимающая программа.Листинг 24.3. Принимающая программа, в которой (ошибочно)


26.3. Использование потоков в функции str_cli

Из книги автора

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