Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Архив1 / docx55 / Отчет №3.docx
Скачиваний:
33
Добавлен:
01.08.2013
Размер:
122.18 Кб
Скачать

Санкт-Петербургский государственный политехнический университет

Факультет технической кибернетики

Кафедра Компьютерные системы и программные технологии

Отчёт по лабораторной работе №3

Дисциплина: "Системное программное обеспечение"

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

Выполнил студент гр. 5081/13 Залеский А. А.

Преподаватель __________ Душутина Е. В.

\

Введение

Обработка исключений начинается в ядре операционной системы. Так, каждому типу исключений поставлен в соответствие свой обработчик, получающий управление в случае возникновения определённого события. Осуществив необходимые действия, ядро Windows передаёт управление потоку, в котором произошло исключение для его дальнейшей обработки. Однако, поток продолжает своё выполнение не с места возникновения исключения, а со строго определённого места - пользовательского диспетчера исключений KiUserExceptionDispatcher, располагающегося в библиотеке NTDLL.DLL. В качестве информации, необходимой для корректной обработки исключения, потоку передаётся вся необходимая информация о месте исключения и его характеристиках -- для этого, в стек потока заносятся структуры EXCEPTION_RECORD и CONTEXT, а указатели на эти структуры передаются в качестве аргументов непосредственно KiUserExceptionDispatcher.

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

typedef struct _EXCEPTION_RECORD {

DWORD ExceptionCode;

DWORD ExceptionFlags;

struct _EXCEPTION_RECORD *ExceptionRecord;

PVOID ExceptionAddress;

DWORD NumberParameters;

ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];

} EXCEPTION_RECORD, *PEXCEPTION_RECORD;

Интересующее нас поле ExceptionFlags предназначено для определения того, является ли данное исключение продолжаемым. В случае, если это не так, будет установлен флаг EXCEPTION_NONCONTINUABLE. Попытка возобновить выполнение потока после возникновения не продолжаемого исключения приведёт к возникновению исключения с кодом EXCEPTION_NONCONTINUABLE_EXCEPTION. Его и нужно отловить.

Как следует из описания, нужно создать ошибку у которой будет установлен флаг EXCEPTION_NONCONTINUABLE, а затем попытаться продолжить её и отловить ошибку о невозможности продолжения процесса.

__try{

RaiseException(0, EXCEPTION_NONCONTINUABLE, 0, NULL);

}

__except (GetExceptionCode()==EXCEPTION_NONCONTINUABLE_EXCEPTION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_EXECUTION){

}

В блоке except проверяем, отловили ли мы ошибку EXCEPTION_NONCONTINUABLE_EXCEPTION и если отловили, выходим из блока. Иначе, пытаемся продолжить выполнение потока. Таким образом, первый раз вызывается команда EXCEPTION_CONTINUE_EXECUTION, а после повторной ошибки, вызывается EXCEPTION_EXECUTE_HANDLER.

Приведу вырезку с сайта MSDN о кодах ошибкок. У отлавливаемой нами ошибки код C0000025.

Выполнение работы

  1. Сгенерировать исключение типа exception_continue_execution отловить его средствамиWin32, написав собственную функцию фильтра. Получить информацию об исключении.

#include <iostream>

#include <windows.h>

DWORD Filter(DWORD ExCode, LPEXCEPTION_POINTERS ExInfo){

printf("Ex_code: %X\n", ExCode );

printf("Ex_address: %X\n",ExInfo->ExceptionRecord->ExceptionAddress);

return(ExCode==EXCEPTION_NONCONTINUABLE_EXCEPTION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_EXECUTION); } //Если код исключения, пришедшего в фильтр не равен EXCEPTION_NONCONTINUABLE то пытаемся продолжить выполнение программы, иначе, выходим из фильтра.

void tmain()

{

int n;

__try{//Вызываем исключение с флагом EXCEPTION_NONCONTINUABLE

RaiseException(0, EXCEPTION_NONCONTINUABLE, 0, NULL);

}

__except (Filter(GetExceptionCode(), GetExceptionInformation())){ // Направляем обработчик в функцию фильтра

}

system("Pause");

return;

}

Результат выполнение программы:

Соседние файлы в папке docx55