- •Введение
- •Выполнение работы
- •Сгенерировать исключение типа exception_continue_execution отловить его средствамиWin32, написав собственную функцию фильтра. Получить информацию об исключении.
- •Сгенерировать исключение при помощи функции RaseException
- •Использовать функции UnhandledExceptionFilter и SetExceptionFilter для необработанных исключений.
- •Обработать вложенные исключения.
- •Исследовать блок try спомощью операторов goto и __leave
Сгенерировать исключение при помощи функции RaseException
Сгенерируем собственное исключение MY_EXCEPTION
#include <stdio.h>
#include <iostream>
#include <windows.h>
using namespace std;
#define MY_EXCEPTION 0x7
DWORD Filter2(LPEXCEPTION_POINTERS exc_inf){ // Фильтр, отлавливающий пользовательскую ошбику.
printf("Ex_code: %X\n",exc_inf->ExceptionRecord->ExceptionCode);
if (exc_inf->ExceptionRecord->ExceptionCode==MY_EXCEPTION) cout<<"It's My Exception!\n"; //Определяем какое исключение выкинулось. Если пользовательское – выводим сообщение об этом.
else return (exc_inf->ExceptionRecord->ExceptionCode==MY_EXCEPTION) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH;
}
void main(INT argc, LPCWSTR argv) {
const char* error = "test message";
__try{
RaiseException(MY_EXCEPTION, 0, sizeof(error), (ULONG_PTR*)error); // Генерируем пользовательское исключение MY_EXCEPTION
}
__except(Filter2(GetExceptionInformation())){
printf("Inner block. After except\n");
}
system("Pause");
}
Использовать функции UnhandledExceptionFilter и SetExceptionFilter для необработанных исключений.
(UnhandEx)
Функция SetExceptionFilterпозволяет назначить обработчик по умолчанию для исключений, которые не были обработаны. Напишем и запустим программу, которая генерирует исключение и не обрабатывает его:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <windows.h>
LONG WINAPI MyUnhandledExceptionFilter(LPEXCEPTION_POINTERS info) {
printf("Unhandled exception\n");
return EXCEPTION_EXECUTE_HANDLER;
}
void main(INT argc, LPCWSTR argv) {
//SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
__try{
RaiseException(0, EXCEPTION_NONCONTINUABLE, 0, NULL);
}
__except (EXCEPTION_EXECUTE_HANDLER){
printf("exception\n");
}
}
Программа завершится ошибкой, в профилировании видим, что вызывается стандартный обработчик необработанных исключений _except_handler4:
Теперь установим пользовательский обработчик необработанных исключений, раскомментировав строку SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
Необработанное исключение поймано:
Видно, что вызывается функция MyUnhandledExceptionFilter:
Обработать вложенные исключения.
Программа генерирует исключение EXECUTE_SINGLE_STEP, отлавливает его, а в обработчике генерирует пользовательское исключение функциейRaiseException,
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <windows.h>
using namespace std;
#define MY_EXCEPTION 0x7
DWORD FirstFilter(DWORD ExCode, LPEXCEPTION_POINTERS ExInfo){ //Внутренний, первый фильтр. Ловит ошибку EXCEPTION_CONTINUE_EXECUTION.
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); }
DWORD SecondFilter(DWORD ExCode, LPEXCEPTION_POINTERS ExInfo){ //Внешний, второй фильтр. Ловит ошибку пошльзователя, выкинутую во внешнем обработчике.
printf("Ex_code: %X\n", ExCode );
printf("Ex_address: %X\n",ExInfo->ExceptionRecord->ExceptionAddress);
return(ExCode == 0x7 ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH);
}
void Exception(){ // Генерация ошибки EXCEPTION_CONTINUE_EXECUTION и ее обработка внутренним фильтром, а так же генерация пользовательской ошибки MY_EXCEPTION
__try{
RaiseException(0, EXCEPTION_NONCONTINUABLE, 0, NULL);
}
__except (FirstFilter(GetExceptionCode(), GetExceptionInformation())){
printf("Betwee two except.\n");
const char* error = "test message";
RaiseException(MY_EXCEPTION, 0, sizeof(error), (ULONG_PTR*)error);
}
}
void main(INT argc, LPCWSTR argv) {
__try{
Exception();
} __except (SecondFilter(GetExceptionCode(), GetExceptionInformation())){
printf("Inner block. After all except\n");
}
system("Pause");
}
Оба исключения были отловлены и обработаны.