介绍部分转自https://www.cnblogs.com/lisuyun/p/5245609.html

程序部分为原创。

Minidump方式保留程序崩溃现场

在Windows平台下用C++开发应用程序,最不想见到的情况恐怕就是程序崩溃,而要想解决引起问题的bug,最困难的应该就是调试release版本了。因为release版本来就少了很多调试信息,更何况一般都是发布出去由用户使用,crash的现场很难保留和重现。目前有一些方法可以解决:崩溃地址 + MAP文件;MAP文件;SetUnhandledExceptionFilter + Minidump。本文重点关注SetUnhandledExceptionFilter + Minidump方式。

一、Minidump文件生成

1、Minidump概念

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

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

2、生成minidump文件

通过drwtsn32、NTSD、CDB等调试工具生成Dump文件, drwtsn32存在的缺点虽然NTSD、CDB可以完全解决,但并不是所有的操作系统中都安装了NTSD、CDB等调试工具。根据MiniDumpWriteDump接口,完全可以程序自动生成Dump文件。MiniDumpWriteDump是MS DbgHelp.dll中的一个API,用于导出当前运行程序的dump。

3、  自动生成Minidump文件

当程序遇到未处理异常(主要指非指针造成)导致程序崩溃死,如果在异常发生之前调用了SetUnhandledExceptionFilter()函数,异常交给函数处理。MSDN中描述为:

Issuing SetUnhandledExceptionFilter replaces the existing top-level exception filter for all existing and all future threads in the calling process.

因而,在程序开始处增加SetUnhandledExceptionFilter()函数,并在函数中利用适当的方法生成Dump文件,即可实现需要的功能。

#include <DbgHelp.h>
#pragma comment(lib,"DbgHelp.lib")//main函数中调用SetUnhandledExceptionFilter
SetUnhandledExceptionFilter(DumpCallback);LONG WINAPI DumpCallback(_EXCEPTION_POINTERS* excp) {boost::mutex::scoped_lock lock(g_dump_mutex);CreateDump(excp);return EXCEPTION_EXECUTE_HANDLER;
}VOID CreateDump(struct _EXCEPTION_POINTERS *pExceptionPointers) {//收集信息CStringW strBuild;strBuild.Format(L"Build: %s %s", __DATE__, __TIME__);CStringW strError;WCHAR* szModuleName = L"my_module_name";strError.Format(L"%s %d , %d ,%d.", szModuleName, pExceptionPointers->ExceptionRecord->ExceptionCode, pExceptionPointers->ExceptionRecord->ExceptionFlags, pExceptionPointers->ExceptionRecord->ExceptionAddress);//生成 mini crash dumpBOOL bMiniDumpSuccessful;WCHAR* szPath = L"./";WCHAR szFileName[MAX_PATH];WCHAR* szAppName = L"DumpFile";WCHAR* szVersion = L"v1.0";DWORD dwBufferSize = MAX_PATH;HANDLE hDumpFile;SYSTEMTIME stLocalTime;MINIDUMP_EXCEPTION_INFORMATION ExpParam;GetLocalTime(&stLocalTime);//GetTempPathW(dwBufferSize, szPath);StringCchPrintfW(szFileName, MAX_PATH, L"%s%s", szPath, szAppName);CreateDirectoryW(szFileName, NULL);//std::wcout << szFileName;StringCchPrintfW(szFileName, MAX_PATH, L"%s%s//%s-%04d%02d%02d-%02d%02d%02d-%ld-%ld.dmp",szPath, szAppName, szVersion,stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay,stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond,GetCurrentProcessId(), GetCurrentThreadId());hDumpFile = CreateFileW(szFileName, GENERIC_READ | GENERIC_WRITE,FILE_SHARE_WRITE | FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);MINIDUMP_USER_STREAM UserStream[2];MINIDUMP_USER_STREAM_INFORMATION UserInfo;UserInfo.UserStreamCount = 1;UserInfo.UserStreamArray = UserStream;UserStream[0].Type = CommentStreamW;UserStream[0].BufferSize = strBuild.GetLength()*sizeof(WCHAR);UserStream[0].Buffer = strBuild.GetBuffer();UserStream[1].Type = CommentStreamW;UserStream[1].BufferSize = strError.GetLength()*sizeof(WCHAR);UserStream[1].Buffer = strError.GetBuffer();ExpParam.ThreadId = GetCurrentThreadId();ExpParam.ExceptionPointers = pExceptionPointers;ExpParam.ClientPointers = TRUE;MINIDUMP_TYPE MiniDumpWithDataSegs = (MINIDUMP_TYPE)(MiniDumpNormal| MiniDumpWithHandleData| MiniDumpWithUnloadedModules| MiniDumpWithIndirectlyReferencedMemory| MiniDumpScanMemory| MiniDumpWithProcessThreadData| MiniDumpWithThreadInfo);bMiniDumpSuccessful = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),hDumpFile, MiniDumpWithDataSegs, &ExpParam, NULL, NULL);return;
}

二、调试Minidump文件

  1. 双击minidump文件(*.dmp)。默认会启动VisualStudio。
  2. 菜单Tools/Options, Debugging/Symbols,增加PDB文件路径。注:如果minidump文件与pdb文件在同一目录,就不用设置这个了。
  3. 若调试的程序需要微软基础库的PDB信息,可以增加一个路径为:http://msdl.microsoft.com/download/symbols
  4. 在界面下方Cache Symbol From symbol…选择本地存储这些Symbols的路径。 注:如果本地已存储过微软基础库的pdb,就直接按照此步操作设置本地路径,不必执行上一步操作了。
  5. 设置代码路径:刚打开的dmp工程,进入解决方案的属性。在这里输入源程序的代码路径。注:一定是sln所在的路径,而不是vcproj的路径!

6. 按F5,debug吧。

Minidump方式保留程序崩溃现场相关推荐

  1. Go程序崩溃现场应该如何保留?

    Go 程序突然莫名崩溃后,当日志记录没有覆盖到错误场景时,还有别的方法排查吗? 没有消灭一切的银弹,也没有可以保证永不出错的程序.我们应当如何捕捉 Go 程序错误?我想同学们的第一反应是:打日志. 但 ...

  2. 现场升级方案:LPC1788采用U盘方式进行程序IAP升级功能的实现

    现场升级方案:LPC1788采用U盘方式进行程序IAP升级功能的实现 闲来无事,总结一下前段时间做过的U盘升级项目.一个新手的成长之路在于善于总结,生活也是一样扯远了,我准备了两个软件环境,一个带操作 ...

  3. 应用程序崩溃定位查找 (二)

    教程的第一部分介绍了 SIGABRT 和 EXC_BAD_ACCESS 的错误,并说明解决他们使用 Xcode 调试器和异常断点的一些策略. 但我们的应用程序仍然有一些问题!它不能完全按照它应该并且有 ...

  4. 程序崩溃 分析工具_程序分析工具| 软件工程

    程序崩溃 分析工具 A program analysis tool implies an automatic tool that takes the source code or the execut ...

  5. C ++标准是否允许未初始化的bool使程序崩溃?

    本文翻译自:Does the C++ standard allow for an uninitialized bool to crash a program? I know that an " ...

  6. cef异常处理_cefSharp在XP下使得程序崩溃记录

    前言:这是一个奇葩的问题,到现在自己还没有搞明白问题出现在哪里,但是从问题总算是解决了,希望看到此文章的大牛,如果知道问题出在什么地方,可以告知一下. [一个在XP系统下面应用程序崩溃问题] 资源: ...

  7. 【Crash】C++程序崩溃排查方法

    windows下C++程序release版本崩溃错误排查方法. 一个你精心设计的24小时不间断运行,多线程的程序,突然运行了几个月后崩了,此问题是非常难以排查的,也是很头疼的问题. 现利用Google ...

  8. 【Qt】Qt信号与槽使用不当,使程序崩溃

    问题描述 跨线程使用Qt信号和槽,信号发送时间间隔小于槽函数处理时间时,造成程序崩溃. 原因分析 跨线程使用Qt信号和槽时,connect默认是QueuedConnection,队列连接方式. 信号传 ...

  9. C++程序崩溃生成dump

    程序在运行时,难免会有一些异常情况发生,特别是在条件不容许去挂调试器的时候,如何快速的定位错误的方法就显得很重要. 日志一直都是一种很重要的定位错误的方法,出得好的日志可以方便程序员快速的定位问题所在 ...

  10. iOS 中捕获程序崩溃日志

    iOS开发中遇到程序崩溃是很正常的事情,如何在程序崩溃时捕获到异常信息并通知开发者,是大多数软件都选择的方法.下面就介绍如何在iOS中实现: 1. 在程序启动时加上一个异常捕获监听,用来处理程序崩溃时 ...

最新文章

  1. HarmonyOS shape 的使用
  2. redis trie
  3. Entity Framework 4.3 中的新特性
  4. intent和手势探测
  5. mfc 饼图绘画_绘画技能干货 | 【人体头颈】的绘画技巧(三)(内含母亲节抽奖公布)...
  6. WordPress WP Photo Album Plus插件‘wppa-tag’跨站脚本漏洞
  7. oracle 生成随机姓名_Oracle 生成随机数,随机字符串
  8. Java基础提高学习笔记2
  9. (5)【整合】基于机器学习的酒店评论文本倾向性分析
  10. AcWing 1934. 贝茜放慢脚步(二路归并)
  11. 深入浅出 CAS,很多想进阿里的倒在了这个知识点
  12. 【知识图谱系列】知识图谱多跳推理之强化学习
  13. 前端字体图标的下载与使用
  14. html 实现b站弹幕,可实现B站 蒙版弹幕 效果的前端组件 —— Barrage UI
  15. java socket是什么_socket系列之什么是socket
  16. 500. 键盘行【我亦无他唯手熟尔】
  17. 排兵布阵 (分组背包)
  18. 电脑屏幕亮度随背景颜色变化
  19. 企业中了勒索病毒该怎么办?可以解密吗?
  20. Gdal关于CAD转SHP格式

热门文章

  1. 腾讯、阿里、京东…互联网大厂2022新年礼盒长啥样?
  2. 详尽的msf——meterpreter——渗透测试教程
  3. 第09章 网格划分自我附加练习-2:圆角结构 、圆柱结构、三角结构划分:
  4. AUTOSAR SWS SOME/IP Transformer
  5. 51单片机采用ADC0808检测ADC_LCD1602显示
  6. 从delphi 10.3到delphi 10.4的改变实务
  7. win10系统office2010每次打开总是出现配置进度
  8. 量子通讯加密技术的技术原理
  9. 计算机考试的话语,鼓励别人考试的句子
  10. creo 根据点坐标文件创建样条曲线