`

windows异常处理__try__except

 
阅读更多

try-except用法   

try except是windows 系统独有的异常处理模型,windows的异常处理模式,称为SEH( structured exception handling ), SEH的异常处理模型主要由try-except语句来完成,与标准的try catch相似。

与C++异常处理模型使用catch关键字来定义异常处理模块,而SEH是采用__except关键 字来定义。并且,catch关键字后面往往好像接受一个函数参数一样,可以是各种类型的异常数据对象;

但是__except关键字则不同,它后面跟的却是一个表达式. 我们知道,函数调用也是一个表达式。

我们来看下面这个例子,这个例子是用来处理栈溢出的异常。

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; }

except参数的值有以下三种:

EXCEPTION_CONTINUE_EXECUTION (–1) 异常被忽略,控制流将在异常出现的点之后,继续恢复运行。   

EXCEPTION_CONTINUE_SEARCH (0) 异常不被识别,也即当前的这个__except模块不是这个异常错误所对应的正确的异常处理模块。系统将继续到上一try- except域中继续查找一个恰当的__except模块。   

EXCEPTION_EXECUTE_HANDLER (1) 异常已经被识别,控制流将进入到__except模块中运行异常处理代码 try-except的关键是如何在__except模块中获得异常错误的相关信息.

Windows提供了两个API函数来获取异常信息:

LPEXCEPTION_POINTERS GetExceptionInformation(VOID); //取得异常相关信息

DWORD GetExceptionCode(VOID); // 取得异常编号 GetExceptionCode()返回异常编号,而GetExceptionInformation()返回更丰富的信息,

EXCEPTION_POINTERS结构如下,

typedef struct _EXCEPTION_POINTERS

{ // exp PEXCEPTION_RECORD ExceptionRecord; PCONTEXT ContextRecord;

} EXCEPTION_POINTERS;

其中EXCEPTION_RECORD类型,它记录了一些与异常相关的信息;

而CONTEXT数据结构体中记录了异常发生时,线程当时的上下文环境,主要包括寄存器的值。

有了这些信息,__except模块便可以对异常错误进行很好的分类和恢复处理,通常我们需要一个过滤函数来辅助。

一般称为是filterfunction.过滤函数只过滤需要处 理的异常。

 int exception_access_violation_filter(LPEXCEPTION_POINTERS p_exinfo)

 {

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处理这个异常

}

于是,你可以这样写这段异常处理代码:

__try { // guarded code }

__except(exception_access_violation_filter(GetExceptionInformation()))

{ // }

__try { // guarded code }

__exceptexception_int_divide_by_zero_filter(GetExceptionInformation()))

{ //exception handling }

SEH异常处理模型中,也可以抛出一个异常。对应的WindowsAPI函数是RaiseException, VOID RaiseException( DWORD dwExceptionCode, // 异常的编号 DWORD dwExceptionFlags, // 异常标记 DWORD nNumberOfArguments, // 参数个数 CONST DWORD *lpArguments // 参数数组首地址 ); 通常,后三个参数基本不用 SEH异常处理还有try-finally.类似于java里的try-catch-finally.但是SEH的try只能和except和finally两者之间的一个搭配,不能有try-except-finnaly. C++异常模型用try-catch语法定义,而SEH异常模型则用try-except语法,与C++异常模型相似,try-except也支持多层的try-except嵌套。

try-except模型中,一个try块只能是有一个except块;而C++异常模型中,一个try块可以有多个catch块。 C++异常模型是按照异常对象的类型来进行匹配查找的;

而try-except模型则不同,它通过一个表达式的值来进行判断. __except关键字后面跟的表达式,它可以是各种类型的表达式,例如,它可以是一个函数调用,或是一个条件表达式,或是一个逗号表达式,或干脆就是一个整 型常量等等。

最常用的是一个函数表达式,并且通过利用GetExceptionCode()或GetExceptionInformation ()函数来获取当前的异常错误信息,便于程序员有效控制异常 错误的分类处理。

 SEH异常处理模型中,异常通过RaiseException()函数抛出。

RaiseException()函数的作用类似于C++异常模型中的throw。

关于SEH异常处理更详细的资料,你可以去看windows via c/c++这本书,中文译名是windows核心编程。不过还是建议你看英文原版,翻译的版本质量不高。

分享到:
评论

相关推荐

    C++ 中try finally关键字详解

    try-finally语句是Microsoft对C和C++语言的扩展,它能使32位的目标程序在异常出现时,有效保证一些资源能够被及时清除,这些资源的清除任务可以包括例如内存的释放,文件的关闭,文件句柄的释放等等。try-finally...

    windows驱动开发技术详解-part2

     5.6.4 结构化异常处理(try-except块)  5.6.5 结构化异常处理(try-finally块)  5.6.6 使用宏需要注意的地方  5.6.7 断言  5.7 小结 第6章 Windows内核函数  本章介绍了Windows内核模式下的一些常用...

    Delphi 获取Windows 打印分辨率.rar

    Delphi 获取Windows 打印分辨率,通过单击窗口中的按钮,直接获取到打印机支持的分辨率大小,为下一步定制打印程序提供依据。以下是核心代码:  Try  Application.MessageBox(pchar('水平分辨率为:' IntToStr...

    Windows驱动开发技术详解的光盘-part1

     5.6.4 结构化异常处理(try-except块)  5.6.5 结构化异常处理(try-finally块)  5.6.6 使用宏需要注意的地方  5.6.7 断言  5.7 小结 第6章 Windows内核函数  本章介绍了Windows内核模式下的一些常用...

    cnnvd爬虫,仅供学习参考。

    'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80 Safari/537.36', 'Connection': 'keep-alive',} r=requests.get(url,headers=header,...

    Python简明教程

    try..except 处理异常 引发异常 如何引发异常 try..finally 使用finally 概括 14. Python标准库 简介 sys模块 命令行参数 更多sys的内容 os模块 概括 15. 更多Python的内容 特殊的方法 单语句块 列表综合 使用...

    python简明教程.chm

    try..except 处理异常 引发异常 如何引发异常 try..finally 使用finally 概括 14. Python标准库 简介 sys模块 命令行参数 更多sys的内容 os模块 概括 15. 更多Python的内容 特殊的方法 单语句...

    简明python教程(chm)

    try..except 处理异常 引发异常 如何引发异常 try..finally 使用finally 概括 14. Python标准库 简介 sys模块 命令行参数 更多sys的内容 os模块 概括 15. 更多Python的内容 特殊的方法 单语句...

    简明python教程

    try..except 处理异常 引发异常 如何引发异常 try..finally 使用finally 概括 14. Python标准库 简介 sys模块 命令行参数 更多sys的内容 os模块 概括 15. 更多Python的内容 特殊的方法 单语句块 ...

    基于PySide6框架+python的智能充电桩调度计费系统前端源码+项目说明文档.zip

    下载安装 Python3.10(Windows 建议使用微软商店) 克隆项目仓库 在项目根目录执行 python3.10 -m pip install -r requirements.txt 使用 python3.10 admin/main.py 与 python3.10 user/main.py 分别启动用户...

    weather.exe

    "User-Agent":"Mozilla/5.0(Windows NT 10.0; WOW64) AppleWebKit/537.36(KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36", "Connection":"keep-alive"} opener=urllib.request.build_opener() headall...

    Python中文手册

    异常 <br>错误 <br>try..except <br> 处理异常 <br>引发异常 <br> 如何引发异常 <br>try..finally <br> 使用finally <br>概括 <br>14. Python标准库 <br>简介 <br>sys...

    内存管理内存管理内存管理

    在大部分操作系统中,内存分配由以下两个简单的函数来处理: void *malloc(long numbytes):该函数负责分配 numbytes 大小的内存,并返回指向第一个字节的指针。 void free(void *firstbyte):如果给定一个由...

    操作系统(内存管理)

    确定您是否有足够的内存来处理数据。 从可用的内存中获取一部分内存。 向可用内存池(pool)中返回部分内存,以使其可以由程序的其他部分或者其他程序使用。 实现这些需求的程序库称为 分配程序(allocators),...

    Delphi使用ADO连接池(存储过程示例)

    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm2 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); procedure ...

    简明 Python 教程.rar

    try..except.........103 引发异常..........105 try..finally.........107 概括.....108 第14章 Python标准库..109 简介.....109 sys模块109 os模块..112 概括.....113 第15章更多Python的内容......114 ...

    DELPHI 5编程实例与技巧

    2.4.2 try...except语句 45 2.4.3 try...finally语句 47 2.5 方法与技巧 48 2.5.1 命名规则 48 2.5.2 在编译时自由设置是否获得提示 信息 48 2.5.3 使用代码模板 49 2.5.4 使用动态多维数组 49 2.5.5 定义两个相互...

    Delphi 5编程实例与技巧

    2.4.2 try...except语句 45 2.4.3 try...finally语句 47 2.5 方法与技巧 48 2.5.1 命名规则 48 2.5.2 在编译时自由设置是否获得提示 信息 48 2.5.3 使用代码模板 49 2.5.4 使用动态多维数组 49 2.5.5 定义两个相互...

    Delphi7.完美经典

    8-1 异常处理存在的目的 8-2 Object Pascal异常的种类 8-2-1 Delphi内建的异常类 8-2-2 自定义异常类 8-3 触发异常的方法 8-3-1 由程序系统自动触发 8-3-2 使用Raise指令触发 8-4 处理异常情况 8-4-1 try…...

Global site tag (gtag.js) - Google Analytics