Windows的异常处理
Windows系统的异常处理有两种:
- 结构化异常处理(SEH,Structured Exception Handling)
- 向量化异常处理(VEH,Vectored Exception Handling)
SEH
Windows定义了SEH机制来规范异常处理代码的设计(对程序员)和编译(对编译器)。
SEH 提供了 终结处理 和 异常处理 两种功能。
- 终结处理:用于保证终结处理块始终可以得到执行,无论被保护的代码块如何结束。
- 异常处理:用于接收和处理被保护块中的代码所发生的异常;
__try
、__except
、__finally
是 Visual C++
编译器为了支持SEH专门定义的关键字。
按照惯例:没有下划线的关键字通常是编程语言所定义的,如上一篇文章提到的C++异常处理,用的就是try、catch;
而加双下划线的关键字通常是编译器定义的。
SEH的终结处理
代码结构如下:
__try
{
// 要保护的代码块
}
__finally
{
// 终结处理块
}
只要保护的代码块被执行,终结处理块就会被执行。除非被保护的代码块终止了当前线程,如使用ExitProcess、ExitThread、TerminateProcess、TerminateThread等。因此终结处理块非常适合做 状态恢复 或 资源释放 等工作。
SEH把被保护块的退出分为正常退出和非正常退出。在终结处理块中可以通过AbnormalTermination函数来获得被保护块的退出方式。
- 正常退出:被保护块得到自然执行并顺序进入终结处理块。函数返回FALSE。
- 非正常退出:被保护块因为发生异常或由于
return
、goto
、break
或continue
等流程控制语句离开被保护块。函数返回TRUE。
除了__try和__finally,终结处理还有个关键字__leave
。它的作用是立即停止执行被保护块,使用__leave关键字的退出也属于正常退出。
SEH的异常处理
代码结构如下:
__try
{
// 要保护的代码块
}
__except(过滤表达式)
{
// 异常处理块
}
除了__try和__except,Visual C++编译器还提供了两个宏来辅助编写异常处理代码:
GetExceptionCode()
:返回异常代码,只能在过滤表达式或异常处理块中使用该宏。
GetExceptionInformation()
:返回一个指向EXCEPTION_POINTER结构的指针,只能在过滤表达式中使用该宏。
typedef struct _EXCEPTION_POINTERS