Win32程序异常捕获处理
作者: MrZhu007
日期; 2019-10-24
博客地址:金色世界
背景说明
程序发生异常时,直接以崩溃(闪退)的方式退出,给用户造成不友好的体验。
编程环境C/C++。VS/MFC界面框架
常见崩溃闪退种类及来源
- 访问错误
- 数组索引访问越界
- 指针对象访问越界
- 访问空指针对象
- 访问无效指针对象
- 迭代器访问越界
- 类型错误
- 使用C格式进行强制转换。
- 堆栈溢出
- 递归调用
- 循环调用
- 消息循环
- 大对象参数
- 大对象变量
- 内存不足
- 异常错误来源
- C++标准异常
- Windows平台Api异常、运行库异常等等结构化异常
错误处理模型
结构化异常处理,是Windows操作系统上,Microsoft对C/C++程序语言做的语法扩展,用于处理异常事件的程序控制结构。
异常事件是打断程序正常执行流程的不在期望之中的硬件、软件事件。硬件异常是CPU抛出的如“除0”、数值溢出等;
结构化异常语法
__try
{
// 受保护执行的代码
}
__except ( 过滤表达式 )
{
// 异常处理代码
}
__try
{
// 受保护执行的代码
}
__finally
{
// 清理用途的代码
}
软件异常是操作系统与程序通过RaiseException语句抛出的异常。
编译选项可以指定编译器使用的错误处理模型
-
EHa
捕获结构化异常和C++异常以C++语法try…catch(…)语法
-
EHsc
捕获C++异常和结构化异常,结构化异常在win32平台使用__try __except _finally语法,并假定C函数不会引发C++异常。此选项是VS工程默认值
-
EHs
仅捕获C++异常
-
无
不使用异常
常见崩溃闪退的错误一般都为结构化异常。来源种类除了C++标准异常,剩下为结构化异常
软件现状
错误处理模型为Ehsc。
使用SetUnhandledExceptionFilter函数。接手软件发生崩溃退出时最后控制。这时候只能进行堆栈等信息打印保存,方便问题定位。
一般使用MiniDumpWriteDump平台Api生成小型转存储文件xxx.dmp.该文件记录软件崩溃时现场。需要对应的pdb符号文件。
但不能解决软件出现类似空指针访问的时候还能继续运行。
初步解决思路
合适的地方使用结构化异常捕获语法。捕获错误,重新运行。不合适的地方,使用转存储文件记录