浅谈SEH和UEF

以前写了篇文章 Windows平台下的异常处理 讨论了Window平台下的一些异常处理方式,然而,简单的把SEH和UEF并列,并不是十分合适,它们并不在一个层级上,UEF相当于SEH框架中的ExceptionFilter表达式,SEH和UEF都属于SEH框架,走同样的异常分发流程,因此实现的功能也类似。OS和CRT的UEF安装在最外面,用户的SEH安装在里面,2者工作范围不同。

SEH的ExceptionFilter表达式和UEF允许用户有3个选择,参见MSDN:http://msdn.microsoft.com/en-us/library/ms680634(v=vs.85).aspx,即

EXCEPTION_EXECUTE_HANDLER

EXCEPTION_CONTINUE_EXECUTION

EXCEPTION_CONTINUE_SEARCH

事实上,从代码实现看,SEH是用户自己定义Filter,而UEF是通过OS已经实现的 UnhandledExceptionFilter 调用的,并且由OS或CRT包装了异常处理代码。如开头所说,它们走同样的异常分发流程,

如果SEH的Filter返回 EXCEPTION_EXECUTE_HANDLER,SEH中的异常处理块会执行,实现代码的飞越,类似于Goto。

由于UEF是由OS或者CRT包装过的,当UEF返回 EXCEPTION_EXECUTE_HANDLER 时,OS或者CRT中的异常处理过程得以执行,一般是ExitProcess或者TerminateProcess,终止进程。

SEH和UEF返回EXCEPTION_EXECUTE_HANDLER,都会导致stack unwind。

SEH和UEF的其它信息可以参见大牛的文章: A Crash Course on the Depths of Win32™ Structured Exception Handling

 

顺便说下VEH,VEH只允许用户给出2个选择,参见MSDN:http://msdn.microsoft.com/en-us/library/ms681419(v=vs.85).aspx,即

EXCEPTION_CONTINUE_EXECUTION

EXCEPTION_CONTINUE_SEARCH

VEH是Windows XP开始引入的功能,不支持EXCEPTION_EXECUTE_HANDLER功能,因此也没有相应的global/local unwind功能。

### Sjlj Seh 的含义及用途 #### 结构化异常处理 (SEH) 结构化异常处理(Structured Exception Handling, SEH)是 Windows 操作系统提供的一种机制,用于捕获并响应程序运行期间发生的错误条件。这种机制允许开发者编写能够优雅地处理各种类型的异常情况的代码[^4]。 在 C/C++ 编程语言中实现 SEH 主要通过 `__try`、`__except` `__finally` 关键字来完成。当发生未预见的情况时,比如除零错误或者非法内存访问,操作系统会触发一个异常事件,并按照预定义的方式寻找最近的一个可以处理该异常的位置来进行相应的恢复操作[^5]。 ```cpp #include <windows.h> #include <stdio.h> int main() { __try { // 可能引发异常的代码段 int a = 0; int b = 1 / a; // 将导致除以零异常 } __except(EXCEPTION_EXECUTE_HANDLER) { printf("Caught an exception\n"); } return 0; } ``` #### Set Jump Long Jump (SJLJ) Set Jump Long Jump(简称 SJLJ),也称为“设置跳跃/远程跳跃”,是一种较早形式的过程间控制转移方法,在某些编程环境中用来模拟 try/catch 或者类似的异常捕捉功能。它依赖于两个标准库函数:`setjmp()` `longjmp()` 来保存当前执行状态以及回溯到之前的状态[^6]。 与 SEH 不同的是,SJLJ 并不是由编译器自动管理堆栈帧信息,而是手动记录返回点并通过显式的调用方式来回退至这些位置。这种方式虽然简单直观但在现代多线程或多处理器架构下效率较低且容易出现问题[^7]。 ```c #include <stdio.h> #include <setjmp.h> jmp_buf env; void function_that_may_fail(void){ if(/* some condition */) longjmp(env, 1); /* 跳转 */ } int main(){ if(setjmp(env)==0){ function_that_may_fail(); }else{ puts("Function failed and we jumped back!"); } return 0; } ``` sjlj seh 是两种不同的异常处理机制,前者更底层且跨平台兼容性较好,后者则是特定于 Windows 系统下的高级特性。对于大多数应用程序开发而言,推荐使用更高层次的语言内置异常处理设施而非直接操纵 sjlj 或 seh[^8]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值