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