调试Release发布版程序的Crash错误(五)

当我们把自己的release版本程序发布出去以后,一般都是在用户的机器上运行。这种情况下,对于第四种方案,因为需要pdb文件才能够正确生成 堆栈调用的函数行号及代码行号,因此方案四只适用于本地release版的调试,否则只能生成不完整的堆栈信息。对于前三种方案,其实只需要用户告知崩溃 地址,然后在本地查找crash地址就可以了,但是定位crash的过程非常不方便,如果crash的情况比较多,前三种方案都不合适。而且,前三种方案 均不能生成堆栈调用信息,对于debug的作用有限。

    下面我们就来看一个更加完善的解决方案。

 

    方案五: SetUnhandledExceptionFilter + Minidump

    SetUnhandleExceptionFilter函数我们已经介绍过了,本方案的思路还是要利用我们自己的异常处理函数,来生成minidump文件。

    1、Minidump概念

    minidump(小存储器转储)可以理解为一个dump文件,里面记录了能够帮助调试crash的最小有用信息。实际上,如果你在 系统属性 -> 高级 -> 启动和故障恢复 -> 设置 -> 写入调试信息 中选择“小内存转储(64 KB)”的话,当系统意外停止时都会在C:/Windows/Minidump/路径下生成一个.dmp后缀的文件,这个文件就是minidump文件,只不过这个是内核态的minidump。

   我们要生成的是用户态的minidump,文件中包含了程序运行的模块信息、线程信息、堆栈调用信息等。而且为了符合其mini的特性,dump文件是压缩过的。

    2、生成minidump文件

    生成minidump文件的API函数是MiniDumpWriteDump,该函数需要dbghelp.lib支持,其原型如下:

    BOOL WINAPI MiniDumpWriteDump(
      __in          HANDLE hProcess ,
      __in          DWORD ProcessId ,
      __in          HANDLE hFile ,
      __in          MINIDUMP_TYPE DumpType ,
      __in          PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam ,
      __in          PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam ,
      __in          PMINIDUMP_CALLBACK_INFORMATION CallbackParam
    );

    在我们的异常处理函数中加入以下代码:

    HANDLE hFile = ::CreateFile( _T("E://dumpfile.dmp"), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
     if( hFile != INVALID_HANDLE_VALUE)
     {
         MINIDUMP_EXCEPTION_INFORMATION einfo;
         einfo.ThreadId = ::GetCurrentThreadId();
         einfo.ExceptionPointers = pExInfo;
         einfo.ClientPointers = FALSE;

        ::MiniDumpWriteDump(::GetCurrentProcess(), ::GetCurrentProcessId(), hFile, MiniDumpNormal, &einfo, NULL, NULL);
        ::CloseHandle(hFile);
     }

    其中,pExInfo变量为异常处理函数PEXCEPTION_POINTERS类型的参数。具体请参考MSDN。

    3、调试minidump

    调试dump文件首先需要pdb文件,因此我们build程序时需要设置 Debug Infomation Format 为 “Program Database(/Zi)”。其次,我们还要确保所用的dump文件与源代码、exe、pdb文件版本是一致的,这要求我们必须维护好程序版本信息。

    调试minidump最方便的环境就是VS了,我们只要将.dmp、.exe、.pdb文件放在一个路径下,保证源代码文件的路径与编译时的路径一致就可以了,剩下的就是VS帮我们完成。双击.dmp文件或者在文件打开工程中选择“dump files”,加载dump文件,然后按F5运行就能直接恢复crash时的现场了,你可以定位crash的代码,可以查看调用堆栈,可以查看线程和模块信息...一切都跟你设置断点调试一样,太强大了!看个截图吧。

调试Release发布版程序的Crash错误(五)

    需要注意的是,对于release版的程序来说,很多代码是经过编译器优化过的,因此定位的时候可能会有所偏差,大家可以考虑设置选项去掉代码优化。

    其他可以调试minidump的工具还有WinDbg等,大家可以查阅相关资料。

    本文主要参考了这篇文章:http://vicchina.51.net/research/other/seh/minidumps/intro.htm

    下一篇,我们将给出一个调试release发布程序的完美解决方案,适合用户量较大的应用发布程序的调试。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值