异常和中断是程序运行时比较重要的2个概念, 异常通常是由程序内部引起的(比较常见的如堆栈溢出, 空指针访问等),中断通常是由外部系统引起的, 外部产生的中断在应用程序中很多时候会以事件或回调的方式通知出来(比如常见的IO事件)。
Windows上应用程序的异常处理是以SEH(structure exception handler)的方式提供的, 关于SEH的实现原理,这里有篇不错的文章可以参考《栈溢出中利用SEH》。
关于SEH的使用,主要包括终止处理(finally)和异常处理(exception).
(1)终止处理主要是由编译器实现的,比如下面代码
__try
{
...
__leave
...
}
__finally
{
...
}
无论是你在try块中过早的return还是在try中发生了异常, 编译器都会确保在任何情况下你的终止处理(finally)代码都能得到执行。
(2)异常处理主要是由操作系统来实现的, 比如下面代码
__try
{
...
}
__except(filter function)
{
...
}
其中filter function可返回以下类型:
EXCEPTION_EXECUTE_HANDLER: 这是告诉系统, 我认识这个异常,请执行我的异常处理代码,然后从接下来的第一行代码开始继续执行
EXCEPTION_CONTINUE_SEARCH: 这个是告诉系统, 我不认识这个异常, 请继续往外抛异常
EXCEPTION_CONTINUE_EXECUTE: 这个是告诉系统, 我已经在调用filter时修正了这个异常, 请从发生异常的地方继续执行
比如我们常见的exception code包括:EXCEPTION_ACCESS_VIOLATION, EXCEPTION_STACK_OVERFLOW,EXCEPTION_INT_DIVIDE_BY_ZERO
上面的几种异常都是硬件异常,是由CPU在运行过程中引发的, 还有一些异常是软件异常,是我们通过调用系统API RaiseException引发的。
我们知道C++的异常处理大概是这样的:
try
{
...
}
catch(int a)
{
...
}
catch(...)
{
...
}
思考C++异常和结构化异常(SEH)是 什么关系?
实际C++异常是通过结构化异常中的软件异常实现的, 也就是通过调用RaiseException实现的, 通过测试我们可以发现VC编译器C++异常的异常号永远是0xE06D7363,对应ASCII码“.msc".
posted on 2014-09-19 21:00
Richard Wei 阅读(4078)
评论(3) 编辑 收藏 引用