异常处理(五、结构化异常处理)
来源:互联网 发布:免费网页数据采集软件 编辑:程序博客网 时间:2024/06/08 11:22
结构化异常处理(Structured Exception Handling,简称SEH)是微软针对Windows程序异常处理进行的扩展,在Visual C++中,它同时支持C和C++语言。SEH不宜与标准C++异常处理和MFC异常处理混用,对于C++程序,微软建议使用标准C++的异常处理。
为了支持SEH,Visual C++中定义了四个关键字(由于这些关键字是非标准关键字,其它编译器不一定支持),用以扩展C 和C++语言:
(1)__except
(2)__finally
(3)__leave
(4)__try
其基本语法为:
(1)__try块被执行;
(2)如果__try块没有出现异常,则执行到__except块之后;否则,执行到__except块,根据filter-expression的值决定异常处理方法:
a. filter-expression的值为EXCEPTION_CONTINUE_EXECUTION (-1)
恢复异常,从发生异常处下面开始执行,异常处理函数本身不被执行;
b. filter-expression的值为EXCEPTION_CONTINUE_SEARCH (0)
异常不被识别,拒绝捕获异常,继续搜索下一个异常处理函数;
c. filter-expression的值为EXCEPTION_EXECUTE_HANDLER (1)
异常被识别,终止异常,从异常发生处开始退栈,一路上遇到的终止函数都被执行。
看看这个例子:
要想这个程序能正确地执行,我们可以在第一个__try块的外面再套一个__try块和一个接收filter-expression返回值为EXCEPTION_EXECUTE_HANDLER的__except块,程序改为:
SEH使用复杂的地方在于较难控制异常处理的流动方向,弄不好程序就"挂"了。如果把例4-1中的__except(puts("in filter"), 1)改为__except(puts("in filter"), -1),程序会进入一个死循环,输出:
为了支持SEH,Visual C++中定义了四个关键字(由于这些关键字是非标准关键字,其它编译器不一定支持),用以扩展C 和C++语言:
(1)__except
(2)__finally
(3)__leave
(4)__try
其基本语法为:
CODE:或:__try
{
...//可能导致异常的被监控代码块
}
__except(filter-expression)
{
...//异常处理函数
}
CODE:其执行的步骤如下:__try
{
...
}
__finally
{
...//终止
}
(1)__try块被执行;
(2)如果__try块没有出现异常,则执行到__except块之后;否则,执行到__except块,根据filter-expression的值决定异常处理方法:
a. filter-expression的值为EXCEPTION_CONTINUE_EXECUTION (-1)
恢复异常,从发生异常处下面开始执行,异常处理函数本身不被执行;
b. filter-expression的值为EXCEPTION_CONTINUE_SEARCH (0)
异常不被识别,拒绝捕获异常,继续搜索下一个异常处理函数;
c. filter-expression的值为EXCEPTION_EXECUTE_HANDLER (1)
异常被识别,终止异常,从异常发生处开始退栈,一路上遇到的终止函数都被执行。
看看这个例子:
CODE:如果我们把__except(puts("in filter"), 1)改为__except(puts("in filter"), 0),程序的输出将变为:#include "stdio.h"
void main()
{
int* p = NULL; // 定义一个空指针
puts("SEH begin");
__try
{
puts("in try");
__try
{
puts("in try");
*p = 0; // 引发一个内存访问异常
}
__finally
{
puts("in finally");
}
}
__except(puts("in filter"), 1)
{
puts("in except");
}
puts("SEH end");
}
程序的输出为:
SEH begin
in try //执行__try块
in try //执行嵌入的__try块
in filter //执行filter-expression,返回EXCEPTION_EXECUTE_HANDLER
in finally //展开嵌入的__finally
in except //执行对应的__except块
SEH end //处理完毕
CODE:程序的执行也告崩溃,弹出对话框。SEH begin
in try //执行__try块
in try //执行嵌入的__try块
in filter //执行filter-expression,返回EXCEPTION_CONTINUE_SEARCH
in finally //展开嵌入的__finally
要想这个程序能正确地执行,我们可以在第一个__try块的外面再套一个__try块和一个接收filter-expression返回值为EXCEPTION_EXECUTE_HANDLER的__except块,程序改为:
CODE:由此可以看出,因为第一个__except的filter-expression返回EXCEPTION_CONTINUE_SEARCH 的原因,"in except1"没有被输出。程序之所以没有崩溃,是因为最终碰到了接收EXCEPTION_EXECUTE_HANDLER的第2个__except。#include "stdio.h"
void main()
{
int* p = NULL; // 定义一个空指针
puts("SEH begin");
__try
{
__try
{
puts("in try");
__try
{
puts("in try");
*p = 0; // 引发一个内存访问异常
}
__finally
{
puts("in finally");
}
}
__except(puts("in filter"), 0)
{
puts("in except");
}
}
__except(puts("in filter"), 1)
{
puts("in except");
}
puts("SEH end");
}
程序输出:
SEH begin
in try //执行__try块
in try //执行嵌入的__try块
in filter1 //执行filter-expression,返回EXCEPTION_CONTINUE_SEARCH
in filter2 //执行filter-expression,返回EXCEPTION_EXECUTE_HANDLER
in finally //展开嵌入的__finally
in except2 //执行对应的__except块
SEH end //处理完毕
SEH使用复杂的地方在于较难控制异常处理的流动方向,弄不好程序就"挂"了。如果把例4-1中的__except(puts("in filter"), 1)改为__except(puts("in filter"), -1),程序会进入一个死循环,输出:
CODE:最后疯狂地输出"in filter",我们把断点设置在__except(puts("in filter"), -1)语句之前,按F5会不断进入此断点。SEH begin
in try //执行__try块
in try //执行嵌入的__try块
in filter //执行filter-expression,返回EXCEPTION_CONTINUE_EXECUTION
in filter
in filter
in filter
in filter
…//疯狂输出"in filter"
- 异常处理(五、结构化异常处理)
- Windows 系统编程初探 (五)结构化异常处理之二:线程相关异常处理
- Windows 系统编程初探 (五)结构化异常处理之二:线程相关异常处理
- 结构化异常处理
- 结构化异常处理
- 结构化异常处理
- 结构化异常处理
- Visual C++异常处理机制原理与应用(五)——C/C++结构化异常处理之try-except异常处理的使用(下)
- SEH结构化异常处理
- 结构化异常处理SEH
- SEH结构化异常处理
- 结构化异常处理SEH
- SEH:结构化异常处理
- 结构化异常处理概念
- 结构化异常处理(SEH)
- SEH(结构异常处理)
- Windows平台下异常处理(二) - 结构化异常
- (windows编程 学习笔记二) 结构化异常处理(异常处理程序和软件异常)
- 异常处理(四、MFC异常处理)
- 关于 python 中使用 lambda 表达式的问题
- JavaScript使用技巧精萃
- 逆向工程打造隐蔽后门
- [原创]幸福?
- 异常处理(五、结构化异常处理)
- Asp.Net细节性问题技巧精萃
- Eclipse工作台中的Preference(3)(完)
- 异常处理(六、各种异常处理的对比)
- 论程序设计方法[转帖]
- [翻译] Effective C++, 3rd Edition, Item 38: 通过 composition(复合)模拟 "has-a"(有一个)或 "is-implemented-in-terms-of"(是根据……实现的)
- c#.net常用函数列表
- 年前工作安排
- 章子怡“嚣张语录”