

码龄10年
暂无认证
34102访问
1
等级
8获赞
3
评论
热门文章
-
一.某岛之人物对象及其加密函数解析
2147
-
一.《传奇M》装备栏遍历的突破口
1789
-
二.某龙端游中LUA的分析和调用
1539
-
一.《轩辕传奇》周围遍历之二叉树
1384
-
一.《UE4奥丁》人物最大属性
1329
最新评论
-
20240228阿⑤
积分乍获得
-
20231124ziher
666
-
20230909八月老师
什麼時候發佈易語言支持庫呢
一.《WIN32》try_except异常深入
Heart
2023-05-24 10:05:10 发布
368
分类专栏: 开发技术 文章标签: try_except 异常
__try_except异常深入
1.try except是windows 系统独有的异常处理模型,windows的异常处理模式,称为SEH( structured exception handling ),
2. SEH的异常处理模型主要由try-except语句来完成,与标准的try catch相似。
3.C++异常处理模型使用catch关键字来定义异常处理模块,而SEH是采用__except关键 字来定义
4.catch关键字后面往往好像接受一个函数参数一样,可以是各种类型的异常数据对象;catch(MyException& e)
5.__except关键字则不同,它后面跟的却是一个表达式(函数调用也可以是一个表达式)
案例分析
1.利用APIGetExceptionCode()获取异常代码
2.except参数的值有以下三种:
EXCEPTION_CONTINUE_EXECUTION (–1) 异常被忽略,控制流将在异常出现的点之后,继续恢复运行。
EXCEPTION_CONTINUE_SEARCH (0) 异常不被识别,也即当前的这个__except模块不是这个异常错误所对应的正确的异常处理模块。系统将继续到上一try- except域中继续查找一个恰当的__except模块。
EXCEPTION_EXECUTE_HANDLER (1) 异常已经被识别,控制流将进入到__except模块中运行异常处理代码 try-except的关键是如何在__except模块中获得异常错误的相关信息.
3.DWORD GetExceptionCode(VOID); // 取得异常编号 例如:EXCEPTION_ACCESS_VIOLATION 访问权限
4.GetExceptionInformation()返回更丰富的信息返回一个EXCEPTION_POINTERS结构体地址这个结构体在TIB结构中存储为一个异常链表中
typedef struct _EXCEPTION_POINTERS { PEXCEPTION_RECORD ExceptionRecord;//记录了一些与异常相关的信息 PCONTEXT ContextRecord; //记录了异常发生时,线程当时的上下文环境,主要包括寄存器的值 //有了这些信息,__except模块便可以对异常错误进行很好的分类和恢复处理,通常我们需要一个过滤函数来辅助 } EXCEPTION_POINTERS;
typedef struct _EXCEPTION_RECORD { 00h DWORD ExceptionCode; //异常事件码 04h DWORD ExceptionFlags; //标志 08h struct _EXCEPTION_RECORD *ExceptionRecord; //下一个EXCEPTION_RECORD结构地址 0ch PVOID ExceptionAddress; //异常发生的地址 10h DWORD NumberParameters; //ExceptionInformation的dword数目 14h ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; }EXCEPTION_RECORD; typedef EXCEPTION_RECORD *PEXCEPTION_RECORD; #define EXCEPTION_MAXIMUM_PARAMETERS 15
5.编写一个过滤函数
int exception_access_violation_filter(LPEXCEPTION_POINTERS p_exinfo)//GetExceptionInformation获取这个结构体地址传进来 { if(p_exinfo->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) { messagebox("access vialation exceptionn"); return EXCEPTION_EXECUTE_HANDLER ; //告诉except处理这个异常 } else return EXCEPTION_CONTINUE_SEARCH; //不告诉except处理这个异常 } int exception_int_divide_by_zero_filter(LPEXCEPTION_POINTERS p_exinfo) { if(p_exinfo->ExceptionRecord->ExceptionCode == EXCEPTION_INT_DIVIDE_BY_ZERO) { return EXCEPTION_EXECUTE_HANDLER; //告诉except处理这个异常 } else return EXCEPTION_CONTINUE_SEARCH; //不告诉except处理这个异常 }
6.调用GetExceptionInformation
__try { // guarded code } __except(exception_access_violation_filter(GetExceptionInformation())) { // }
7.调用GetExceptionCode
long WINAPI FilterFunc(DWORD dwExceptionCode) { return (dwExceptionCode == STATUS_STACK_OVERFLOW) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH; }
UINT WINAPI ThreadFunc(LPVOID param) { __try { // guarded code } __except (FilterFunc(GetExceptionCode())) { // 如果是栈溢出,进行处理。 } return TRUEt; }
SEH异常处理模型中,也可以抛出一个异常
1.对应的WindowsAPI函数是RaiseException,
VOID RaiseException( DWORD dwExceptionCode, // 异常的编号 DWORD dwExceptionFlags, // 异常标记 DWORD nNumberOfArguments, // 参数个数 CONST DWORD *lpArguments // 参数数组首地址 ); 通常,后三个参数基本不用 SEH异常处理还有try-finally
2. SEH异常处理模型中,异常通过RaiseException()函数抛出。
3.RaiseException()函数的作用类似于C++异常模型中的throw。
4.用try-except语法,与C++异常模型相似,try-except也支持多层的try-except嵌套。
5.try-except模型中,一个try块只能是有一个except块;而C++异常模型中,一个try块可以有多个catch块。 C++异常模型是按照异常对象的类型来进行匹配查找的;
6.而try-except模型则不同,它通过一个表达式的值来进行判断. __except关键字后面跟的表达式,它可以是各种类型的表达式,
例如,它可以是一个函数调用,或是一个条件表达式,或是一个逗号表达式,或干脆就是一个整 型常量等等。
关于SEH更详细的可以《windows核心编程》


评论列表