码龄10年
暂无认证
43389
访问
1
等级
8
获赞
3
评论
热门文章
-
一.某岛之人物对象及其加密函数解析
2654
-
一.《传奇M》装备栏遍历的突破口
2282
-
二.某龙端游中LUA的分析和调用
2036
-
一.窗口坐标与屏幕坐标
1757
-
一.《轩辕传奇》周围遍历之二叉树
1755
最新评论
-
20240228阿⑤
积分乍获得
-
20231124ziher
666
-
20230909八月老师
什麼時候發佈易語言支持庫呢
一.《WIN32》try_except异常深入
Heart
2023-05-24 10:05:10 发布
451
分类专栏: 开发技术 文章标签: 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 155.编写一个过滤函数
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核心编程》
网友评论
0条评论 0人参与
评论列表
0
0