本文来源于本人的培训PPT文档,时间原因,本人也就懒得去重新梳理这些文本的表达方式了,看起来可能有些吃力,还望见谅,下面就开始正题吧。
当我们编写的程序出现错误现象时,我们是怎么去解决的?
让测试人员复现错误步骤,然后调试。
分析错误发生原因,然后调试工程试图复现错误。
根据错误地址查找错误代码行。
增加日志输出记录函数运行的流水线。
......
这些到底是不是我们想要的?
错误难复现怎么办?
无法得到错误地址怎么办?(机器无串口输出等)
软件已经发布出去,在用户端发生的错误怎么办?
通过体力劳动频繁的增加或删除打印语句,项目时间不够怎么办?
那么我们怎样才能够快速准确的修复程序运行时的错误?
能够知道错误发生的具体代码行。
能够得到运行时函数堆栈信息。
能够得到函数运行的变量值信息。
发生错误时能够自动保存上述信息到日志文件。
能够通过工具分析日志文件并还原到错误现场。
能够得到运行时函数堆栈信息。
能够得到函数运行的变量值信息。
发生错误时能够自动保存上述信息到日志文件。
能够通过工具分析日志文件并还原到错误现场。
那么这个就是今天我们要将的主题之一Dump文件了,Dump文件能帮我们记录当前程序运行时的函数调用堆栈,内存值信息等。
我们怎么生成Dump文件呢?
在windows桌面平台可以通过MiniDumpWriteDump函数保存当前程序的Dump文件,那么这个函数需要的参数其中就有一个_EXCEPTION_INFORMATION 结构体指针,相信使用过SEH(结构化异常处理)的都熟悉这个结构体,不熟悉的可以去网上查阅相关资料,在此我就不详细说明了。MiniDumpWriteDump函数一般都是我们在异常捕获后认为调用本函数后生成Dump文件。当然我们的程序不是所有的代码都加上了SEH处理代码段,这个时候SetUnhandledExceptionFilter函数就派上用场了,他可以帮助我们得到未捕获的异常通知,同时我们也可以处理该异常,当然写入Dump文件也不在话下。
ps:通过C++异常捕获代码(try,catch(...))捕获到的结构化异常需要通过_set_se_translator函数将c++异常转化为结构化异常。以上的Dump文件生成也可以通过google的break pad开源项目帮我们自动生成dump文件,要比自己写的简单很多,只需要初始化一下就可以了。
Wince上的Dump文件生成
与windows桌面平台的区别在于wince是嵌入式系统,这个是废话,那么系统也是可定制的,wince上的Dump文件生成是被放到了错误报告机组件上去的,需要OS加入错误报告组件,如果未加入该组件dump文件也无法生成。当组件加入后如果程序有异常产生系统会帮助我们生成Dump文件,但是为了我们程序的健壮性我们还是需要人为的加入异常捕获机制,那么就需要我们手动写入Dump文件了。
以下为wince上生成Dump文件需要的API函数:
MiniDumpWriteDump函数在wince上是不可用的,对应的函数为ReportFault。
SetUnhandledExceptionFilter函数在wince上也是不可用的,无100%替代函数,但是我们可以用AddVectoredExceptionHandler来获取异常的通知,但是无法处理异常,只做通知作用,通知后继续由操作系统处理,这样就可能导致程序退出。
ps:本函数是wince未公开的函数,本人通过查看coredll的导出函数查询到,具体定义请查看MSDN上的桌面平台版本,需要自动通过LoadLibrary和GetProcAddress函数获取该函数指针来调用。
_set_se_translator函数依然在wince上不支持。
最后一个话题就是如何通过Windbg还原错误现场了,这个我就不具体说明了,给大家一些资源,借花献佛: