__try/__except 能捕获 windows 结构化异常,如 exception_access_violation、exception_integer_divide_by_zero、exception_stack_overflow 和 exception_invalid_handle,但仅限当前线程当前函数栈,不处理 c++ 异常。

C++ 的 try/catch 捕不到崩溃,必须用 Windows 原生 SEH(__try/__except)或 SetUnhandledExceptionFilter 才能真正拦截访问违规、除零、栈溢出等底层异常。
__try/__except 能捕获哪些崩溃?
它专为 Windows 结构化异常设计,可响应硬件级错误,比如:
-
ACCESS_VIOLATION(解引用空指针、野指针读写) -
INTEGER_DIVIDE_BY_ZERO(整数除零) -
STACK_OVERFLOW(递归过深或大数组栈分配) -
INVALID_HANDLE(非法句柄操作)
但注意:__try/__except 只对当前函数调用栈生效,不能跨线程捕获;且它不处理 C++ 异常(throw 抛出的),那是 try/catch 的职责。
filter-expression 返回值决定后续行为
__except 后面的表达式不是布尔值,而是三个预定义常量之一:
-
EXCEPTION_EXECUTE_HANDLER:执行__except块,然后从__try块外继续执行(**不推荐用于崩溃场景,栈已损坏,强行恢复极易二次崩溃**) -
EXCEPTION_CONTINUE_SEARCH:忽略本次异常,交由上层 SEH 处理器或系统默认处理(最常用) -
EXCEPTION_CONTINUE_EXECUTION:**极危险**——让 CPU 重新执行触发异常的那条指令(仅适用于可修复的瞬时状态,如页面未提交,普通代码慎用)
典型写法是:__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH),但生产环境更建议统一走 EXCEPTION_CONTINUE_SEARCH,再靠全局过滤器兜底。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
SetUnhandledExceptionFilter 是更可靠的兜底方案
相比分散的 __try/__except,注册全局异常过滤器更实用:
- 它能捕获所有未被任何
__try/__except拦下的 SEH 异常 - 支持在崩溃瞬间调用
MiniDumpWriteDump生成 dmp 文件,供 WinDbg 分析 - 可在 handler 中调用
ExitProcess或弹窗提示,避免黑屏退出
关键点:SetUnhandledExceptionFilter 必须在程序启动早期(如 main 或 WinMain 开头)调用,且仅对当前线程有效;多线程程序需为每个线程单独设置(或改用 SetThreadExceptionFilter,但 Vista+ 才支持)。
混合使用 SEH 和 C++ 异常的风险点
当 C++ 代码同时启用 /EHsc(标准异常)和 SEH(/EHa)时,编译器行为会变得不可预测:
- 局部对象析构可能部分执行,也可能跳过——取决于异常类型和展开路径
-
__finally块在 C++ 异常传播中不一定执行(它只响应 SEH 展开) - 第三方库若内部抛 C++ 异常,而你用
__except捕获,GetExceptionCode()返回的是STATUS_CPP_EXCEPTION,不是EXCEPTION_ACCESS_VIOLATION,容易误判
真正体面的崩溃处理,从来不是靠“恢复执行”,而是快速记录上下文(线程 ID、寄存器、堆栈)、保存 dump、释放关键资源(如临时文件、独占句柄)、再干净退出。SEH 是手段,不是目的;别指望它把崩溃变正常。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










