SEH(结构化异常处理)

上传人:ll****x 文档编号:243441211 上传时间:2024-09-23 格式:PPT 页数:28 大小:127KB
返回 下载 相关 举报
SEH(结构化异常处理)_第1页
第1页 / 共28页
SEH(结构化异常处理)_第2页
第2页 / 共28页
SEH(结构化异常处理)_第3页
第3页 / 共28页
点击查看更多>>
资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,SEH(结构化异常处理),1,SEH,(“Structured Exception Handling”),即结构化异常处理.是Windows操作系统提供给程序设计者的强有力的处理程序错误或异常的武器。,2,大家都知道,在C+中有较完善的异常处理机制,同样在C语言中也有很不错的异常处理机制来支持。那么为什么现在此处还在讨论操作系统平台中所提供的异常处理机制呢?,3,在许多系统中,编程语言所提供的异常处理机制的实现,都是建立在操作系统中所提供的异常处理机制之上,如Windows平台上的VC编译器所实现的C+异常处理模型,它就是建立在SEH机制之上的 。具体关系图如下:,4,5,因此,操作系统平台中所提供的异常处理机制是非常有必要的。而且,异常处理机制的实现也是操作系统设计时的一个重要课题。微软在Windows中引入SEH的主要动机是为了便于操作系统本身的开发。操作系统的开发人员使用SEH,使得系统更加强壮。我们也可以使用SEH,使我们的自己的程序更加强壮。,6,使用SEH的好处就是当你编写程序时,只需要关注程序要完成的任务。如果在运行时发生什么错误,系统会发现并将发生的问题通知你。,这样的分离,可以使你集中精力处理眼前的工作,而将可能发生的错误放在后面处理。,7,我们虽然都知道,SEH是Windows系列操作系统平台提供的一种非常完善的异常处理机制。但这毕竟有些过于抽象了,对于程序员而言,它应该有一套类似于像C+中那样的,try,catch,throw,等几个关键字组成的完整的异常处理模型。,8,SHE确实也有类似的语法,它由如下几个关键字组成:_try_except_finally_leave,9,注意!,不要将结构化异常处理同C+的异常处理相混淆。C+异常处理是一种不同形式的异常处理,其形式是使用C+关键字catch和throw。微软的Visual C+支持C+的异常处理,并且在内部实现上利用了已经引入到编译程序和Windows操作系统的结构化异常处理的功能,。,10,SEH实际包含两个主要功能:,结束处理( termination handling ),异常处理( exception handling ),11,结束处理,一个结束处理程序能够确保去调用和执行一个代码块(结束处理程序,termination handler),而不管另外一段代码(保护体,guarded body)是如何退出的。结束处理程序的文法结构(使用微软的Visual C+编译程序)如下:,12,_ try和_ finally关键字用来标出结束处理程序两段代码的轮廓。在上面的代码段中,操作系统和编译程序共同来确保结束处理程序中的_ finally代码块能够被执行,不管保护体(_try块)是如何退出的。不论你在保护体中用return,还是goto,或者是longjump,结束处理程序(_finally块)都将被调用。,13,来看一个简单的程序:,#include ,void main()puts(hello);_tryputs(_try块中);/ 注意,下面return语句直接让函数返回了return;_finallyputs(_finally块中);,puts(world);,程序运行结果如下:hello_try块中_finally块中Press any key to continue,由此可见:,不管在何种情况下,在离开当前的作用域_finally块区域内的代码都将会被执行到,14,_finally块被执行的流程,无外乎三种情况:,顺序执行到_finally块区域内的代码,这种情况很简单,容易理解,goto语句或return语句引发的程序控制流离开当前_try块作用域时,系统自动完成对_finally块代码的调用,由于在_try块中出现异常时,导致程序控制流离开当前_try块作用域,这种情况下也是由系统自动完成对_finally块的调用,15,无论是第2种,还是第3种情况,毫无疑问,它们都会引起很大的系统开销,编译器在编译此类程序代码时,它会为这两种情况准备很多的额外代码。 一般第2种情况,被称为“局部展开”;第3种情况,被称为“全局展开” 。,16,对于第2种情况,程序员完全可以有效地避免它,避免“局部展开”引起的不必要的额外开销。在一个函数中,可能有多处的return语句。针对这种情况,SEH提供了一种非常有效的折衷方案,那就是_leave关键字所起的作用,它既具有像goto语句和return语句那样类似的作用(由于检测到某个程序运行中的错误,需要马上离开当前的_try块作用域),但是又避免了“局部展开” 的额外开销。,来看一个简单的例子:,17,#include ,void main(),puts(hello);,_try,int* p;,puts(_try块中);,/ 直接跳出当前的_try作用域,_leave;,p = 0;,*p = 25;,_finally,puts(_finally块中);,puts(world);,程序运行结果如下:hello_try块中_finally块中worldPress any key to continue,程序中利用_leave关键字,在执行错误语句p=0;*p=25;之前,马上离开当前的_try块作用域 ,避免了“局部展开” 的额外开销 。,建议大家在编程时不妨多用_leave关键字来提高程序的性能。,18,结束处理小结:,1、 “不管在何种情况下,在离开当前的作用域时,finally块区域内的代码都将会被执行到”,这是核心法则。,2、 goto语句和return语句,在其它少数情况下,break语句以及continue语句等,它们都可能会导致程序的控制流非正常顺序地离开_try作用域,此时会发生SEH的“局部展开”。记住,“局部展开”会带来较大的开销,因此,程序员应该尽可能采用_leave关键字来减少一些不必要的额外开销。,19,异常处理,异常是我们不希望有的事件,异常分为硬件异常和软件异常。其中CPU引发的异常,就是所谓的硬件异常;操作系统和应用程序引发相应的异常,称为软件异常。,当出现一个硬件或软件异常时,操作系统向应用程序提供机会来考察是什么类型的异常被引发,并能够让应用程序自己来处理异常。,下面就是异常处理程序的文法结构(使用微软的Visual C+编译程序):,20,注意:_except关键字。每当你建立一个try块,它必须跟随一个finally块或一个except块。一个try 块之后不能既有finally块又有except块。但可以在try-except块中嵌套try-finally块,反过来也可以。,21,与结束处理程序不同,异常过滤器和异常处理程序是通过操作系统直接执行的,编译程序在计算异常过滤器表达式和执行异常处理程序方面不做什么事。,异常过滤器(exception filter)跟在_except关键字后面 ,它可以是各种类型的表达式,例如,它可以是一个函数调用,或是一个条件表达式,或是一个逗号表达式,或干脆就是一个整型常量等等。操作系统根据其计算后的不同结果,对异常进行不同的处理。,22,MSDN中对查找匹配恰当的异常处理模块的过程等几条规则如下:,受监控的代码模块被执行(也即,_try,定义的模块代码);,如果上面的代码执行过程中,没有出现异常的话,那么控制流将转入到,_except,子句之后的代码模块中;,如果出现异常的话,那么控制流将进入到,_except,后面的表达式中,也即首先计算这个表达式的值,之后再根据这个值,来决定做出相应的处理。,23,异常过滤器表达式的值有三种情况,如下:,1、EXCEPTION_CONTINUE_EXECUTION (1) ,表示异常被忽略,控制流将在异常出现点之后,继续恢复运行。,2 、EXCEPTION_CONTINUE_SEARCH (0) ,表示异常不被识别,也即当前的这个_except模块不是这个异常错误所对应的正确的异常处理模块。系统将继续到上一层的try-except域中继续查找一个恰当的_except模块。如果找不到,将报错。,3、EXCEPTION_EXECUTE_HANDLER (1) ,表示异常已经被识别,也即当前的这个异常错误,系统已经找到了并能够确认,这个_except模块就是正确的异常处理模块。控制流将进入到_except模块中。,24,下面通过一个简单的例子来加深对以上规则的理解:,#include ,#include,void main(),puts(hello);,/ 定义受监控的代码模块,_try,int a,b,c;a=0;b=1;,c=b/a;,puts(in try);,/定义异常处理模块,_except(1),puts(in except);,puts(world);,为方便理解,异常过滤器直接使用整型常量。对于程序中的异常,修改该整型常量的值,程序的运行结果各不相同。,25,异常处理小结:,(1) C+异常模型用try-catch语法定义,而SEH异常模型则用try-except语法;,(2) 与C+异常模型相似,try-except也支持多层的try-except嵌套。,(3) 与C+异常模型不同的是,try-except模型中,一个try块只能是有一个except块;而C+异常模型中,一个try块可以有多个catch块。,26,(4) 与C+异常模型相似,try-except模型中,查找搜索异常模块的规则也是逐级向上进行的。但是稍有区别的是,C+异常模型是按照异常对象的类型来进行匹配查找的;而try-except模型则不同,它通过一个表达式的值来进行判断。如果表达式的值为1,(EXCEPTION_EXECUTE_HANDLER),,表示找到了异常处理模块;如果值为0,(EXCEPTION_CONTINUE_SEARCH),,表示继续向上一层的try-except域中继续查找其它可能匹配的异常处理模块;如果值为-1,(EXCEPTION_CONTINUE_EXECUTION),,表示忽略这个异常,注意这个值一般很少用,因为它很容易导致程序难以预测的结果,例如,死循环,甚至导致程序的崩溃等。,27,我讲的比较浅,想要进一步了解SEH,建议大家仔细阅读Windows核心编程。,28,
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!