VS2017下C++ Win32应用如何捕获0xC00002B5与0xC000041D异常
异常捕获失败原因说明
0xC00002B5(运行时代码完整性校验异常)与0xC000041D(多浮点故障异常)都属于Windows系统层面的结构化异常(SEH),既不是标准C规范定义的异常类型,也不在MFC CATCH_ALL的默认捕获范围内,所以你用常规的C try/catch、MFC异常捕获宏都无法捕获到这两类异常。你提供的复现代码触发的就是double类型转long溢出导致的浮点类SEH异常。
可落地的捕获方案
方案1:使用VS专属的SEH扩展语法
__try/__except直接捕获#include <windows.h> __try { // 放置触发异常的代码 const double NULLNUM = 1e+12; double dOvrdVal = NULLNUM; long lVal = (long)dOvrdVal; lVal++; } __except (EXCEPTION_EXECUTE_HANDLER) { DWORD exceptionCode = GetExceptionCode(); if (exceptionCode == 0xC00002B5 || exceptionCode == 0xC000041D) { ASSERT(FALSE); // 补充你的自定义异常处理逻辑 } }注意:
__try块内不能直接定义带析构函数的C++对象,否则会编译报错,需要把带析构的逻辑封装到内部独立代码块中。方案2:修改编译选项让标准C++
try/catch支持捕获SEH异常
打开VS项目属性面板,依次进入C/C++→代码生成→启用C++异常,选择选项是,但有 SEH 异常 (/EHa),配置完成后你之前写的C++try/catch就可以正常捕获这两类异常。该方案会带来少量性能开销,且属于Windows平台专属配置,不支持跨平台编译。方案3:设置全局异常兜底钩子
如果你需要全局捕获进程内所有未处理的这类异常,可以在程序初始化阶段调用SetUnhandledExceptionFilter注册全局异常处理函数:#include <windows.h> LONG WINAPI GlobalExceptionFilter(_In_ PEXCEPTION_POINTERS pExceptionInfo) { DWORD exceptionCode = pExceptionInfo->ExceptionRecord->ExceptionCode; if (exceptionCode == 0xC00002B5 || exceptionCode == 0xC000041D) { // 全局处理逻辑 return EXCEPTION_EXECUTE_HANDLER; } return EXCEPTION_CONTINUE_SEARCH; } // 程序初始化时执行一次即可 SetUnhandledExceptionFilter(GlobalExceptionFilter);
调试器中断问题补充
如果调试时不想让调试器在抛出这两类异常时自动中断,可以在VS调试状态下打开调试→窗口→异常设置,手动添加这两个异常码到Win32异常列表后,取消对应条目的勾选即可。
内容的提问来源于stack exchange,提问作者MTR
相关产品推荐
相关产品推荐

