VS生成dump文件和调试dump文件
在程序崩溃时,需要对异常的情况进行捕获,并捕获到的堆栈信息保持下来。Windows操作系统提供了一个API函数可以在程序crash之前有机会处理这些异常,就是 SetUnhandleExceptionFilter函数。(C++也有一个类似函数set_terminate可以处理未被捕获的C++异常。)
一、函数介绍:
1、SetUnhandleExceptionFilter函数的定义如下:
SetUnhandledExceptionFilter(_In_opt_ LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter);
而LPTOP_LEVEL_EXCEPTION_FILTER的定义如下
typedef LONG (WINAPI *PTOP_LEVEL_EXCEPTION_FILTER)(_In_ struct _EXCEPTION_POINTERS *ExceptionInfo);typedef PTOP_LEVEL_EXCEPTION_FILTER LPTOP_LEVEL_EXCEPTION_FILTER;typedef struct _EXCEPTION_POINTERS {PEXCEPTION_RECORD ExceptionRecord;PCONTEXT ContextRecord;
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
所以定义一个lpTopLevelExceptionFilter函数去处理异常。而lpTopLevelExceptionFilter函数的参数类型是*PEXCEPTION_POINTERS。
2、另一个API函数是写生成dump文件的函数MiniDumpWriteDump,该函数定义如下:
BOOL
WINAPI
MiniDumpWriteDump(_In_ HANDLE hProcess,_In_ DWORD ProcessId,_In_ HANDLE hFile,_In_ MINIDUMP_TYPE DumpType,_In_opt_ PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,_In_opt_ PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,_In_opt_ PMINIDUMP_CALLBACK_INFORMATION CallbackParam);
第四个参数MINIDUMP_TYPE是转存奔溃信息的枚举类型,不同的枚举值保存奔溃信息范围不同,带来的影响就是dump文件的大小。MINIDUMP_TYPE的定义如下:
typedef enum _MINIDUMP_TYPE {MiniDumpNormal = 0x00000000,MiniDumpWithDataSegs = 0x00000001,MiniDumpWithFullMemory = 0x00000002,MiniDumpWithHandleData = 0x00000004,MiniDumpFilterMemory = 0x00000008,MiniDumpScanMemory = 0x00000010,MiniDumpWithUnloadedModules = 0x00000020,MiniDumpWithIndirectlyReferencedMemory = 0x00000040,MiniDumpFilterModulePaths = 0x00000080,MiniDumpWithProcessThreadData = 0x00000100,MiniDumpWithPrivateReadWriteMemory = 0x00000200,MiniDumpWithoutOptionalData = 0x00000400,MiniDumpWithFullMemoryInfo = 0x00000800,MiniDumpWithThreadInfo = 0x00001000,MiniDumpWithCodeSegs = 0x00002000,MiniDumpWithoutAuxiliaryState = 0x00004000,MiniDumpWithFullAuxiliaryState = 0x00008000,MiniDumpWithPrivateWriteCopyMemory = 0x00010000,MiniDumpIgnoreInaccessibleMemory = 0x00020000,MiniDumpWithTokenInformation = 0x00040000,MiniDumpWithModuleHeaders = 0x00080000,MiniDumpFilterTriage = 0x00100000,MiniDumpWithAvxXStateContext = 0x00200000,MiniDumpWithIptTrace = 0x00400000,MiniDumpValidTypeFlags = 0x007fffff,
} MINIDUMP_TYPE;
关于上面枚举值对应保存数据范围的介绍可参考MINIDUMP_TYPE详解_神知道下一秒会发生什么的博客-CSDN博客_minidump_type
下面介绍部分枚举值:
MiniDumpNormal
常选值,该类型仅包含捕获进程中所有线程的堆栈跟踪的必要信息。
MiniDumpWithDataSegs
包含来自所有加载模块中的可写数据段,此选项会使minidump文件显著增大,对每个模块的控制使用了MODULE_WRITE_FLAGS枚举类型的ModuleWriteDataSeg枚举值。如果我们希望查看全局变来那个值,但有不想使用MiniDumpWithFullMemory,可以使用此选项。
MiniDumpWithFullMemory
包含进程中所有可以访问的内存信息,原始内存信息包含在文件的末端,所以不用原始内存信息可以直接映射数据结构。但是该选项会造成minidump文件非常巨大。
使用该选项可以查看存储在栈上、堆上、模块数据段的所有数据。甚至还可以看到线程和进程环境块(Process Environment Block和Thread Environment Bolck, PEB和TEB)的数据。这些没有公开的数据结构可以给我们的调试提供无价的帮助。
MiniDumpWithHandleData
包含生成dump文件时活跃的系统句柄的高级别信息。
使用该选项minidump会包括故障时刻进程故障表里面的所有句柄。可以用WinDbg的!handle来显示这些信息。
MiniDumpFilterMemory
栈内存的内容会在保存到minidump前被过滤,除了重建栈跟踪所必须的指针,其他都会被用0数据覆盖。即调用栈可以被重建,但是所有局部变量和函数参数的值都是0。此选项只影响线程栈占用内存的内容。其他内存(比如堆)不受影响。如果使用了MiniDumpWithFullMemory,这个标志就不起作用了。
第五个参数定义如下:
typedef struct _MINIDUMP_EXCEPTION_INFORMATION {DWORD ThreadId;PEXCEPTION_POINTERS ExceptionPointers;BOOL ClientPointers;
} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION;
上述PEXCEPTION_POINTERS 为异常捕获指针。
二、demo如下:
//创建dmp文件头文件.h
#pragma once
#include <string>
#include <memory>
using namespace std;
class CCreateDump
{
public:CCreateDump();~CCreateDump(void);static CCreateDump* Instance();static long __stdcall UnhandleExceptionFilter(_EXCEPTION_POINTERS* ExceptionInfo);//声明Dump文件,异常时会自动生成。会自动加入.dmp文件名后缀void DeclarDumpFile(std::string dmpFileName = "");
private:static std::string m_strDumpFile;static shared_ptr<CCreateDump*> m_sptrInstance;
};/
创建dmp的.cpp文件
#include <Windows.h>
#include "CListenDump.h"
#include <DbgHelp.h>
#pragma comment(lib, "dbghelp.lib")std::shared_ptr<CCreateDump*> CCreateDump::m_sptrInstance = make_shared<CCreateDump*>();
std::string CCreateDump::m_strDumpFile = "";CCreateDump::CCreateDump()
{
}CCreateDump::~CCreateDump(void)
{}long CCreateDump::UnhandleExceptionFilter(_EXCEPTION_POINTERS* ExceptionInfo)
{HANDLE hFile = CreateFile(m_strDumpFile.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);if (hFile != INVALID_HANDLE_VALUE){MINIDUMP_EXCEPTION_INFORMATION ExInfo;ExInfo.ThreadId = ::GetCurrentThreadId();ExInfo.ExceptionPointers = ExceptionInfo;ExInfo.ClientPointers = FALSE;// write the dumpBOOL bOK = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL);CloseHandle(hFile);if (!bOK){DWORD dw = GetLastError();//写dump文件出错处理,异常交给windows处理return EXCEPTION_CONTINUE_SEARCH;}else{ //在异常处结束return EXCEPTION_EXECUTE_HANDLER;}}else{return EXCEPTION_CONTINUE_SEARCH;}
}void CCreateDump::DeclarDumpFile(std::string dmpFileName)
{SYSTEMTIME syt;GetLocalTime(&syt);char szTime[MAX_PATH];sprintf_s(szTime, MAX_PATH, "[%04d-%02d-%02dT%02d-%02d-%02d]", syt.wYear, syt.wMonth, syt.wDay, syt.wHour, syt.wMinute, syt.wSecond);m_strDumpFile = dmpFileName + std::string(szTime);m_strDumpFile += std::string(".dmp");SetUnhandledExceptionFilter(UnhandleExceptionFilter);
}CCreateDump* CCreateDump::Instance()
{if (*m_sptrInstance == NULL){m_sptrInstance = make_shared<CCreateDump*>(new CCreateDump);}return *m_sptrInstance;
}//主函数cpp文件如下:
// CreateDump.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
#include <iostream>
#include "CListenDump.h"
#include<windows.h>
#include<stdio.h>
int main()
{char szPath[512] = { 0 };//查找可执行文件路径,将dump文件写入可执行文件路径下GetModuleFileName(NULL, szPath, sizeof(szPath) - 1);printf("path:%s\n", szPath);std::string strFilePathTmp = szPath;std::string strDumPath = "";if (strFilePathTmp.rfind(".exe") != string::npos){int nIndex = strFilePathTmp.rfind("\\");if (nIndex != -1){strDumPath = strFilePathTmp.substr(0,nIndex+1);}}strDumPath = strDumPath + "dumpfile";CCreateDump::Instance()->DeclarDumpFile(strDumPath);int nSub = 0;int nValue = 10 / nSub;std::cout << "Hello World!\n";return 0;
}
上述产生dmp文件程序编写参考于Dump文件的生成和使用_不当初-CSDN博客_dump文件
三、调试dmp文件如下:
上述demo运行产生的dmp文件使用VS打开,本文工具使用VS2017,
(1)设置pdb路径
pdb路径如红笔所示
(2)设置源代码路径:
(3)点击运行
调试结果如下:
VS生成dump文件和调试dump文件相关推荐
- vscode调试html文件,vscode调试html文件
1. vscode调试html文件 主要说明使用使用Debugger for Chrome插件如何配置,以及Nodejs的方式调试. 本文的配置方式是基于deepin系统的,适用于所有debian系的 ...
- 020 Android之so文件动态调试
文章目录 ELF文件格式查看工具 so文件加载时的函数执行顺序 so文件动态调试 so文件调试技巧 使用ida动态调试的那些坑 进程显示不全 illegal segment bitness more ...
- VS2015调试dump文件时提示未找到xxx.exe或xxx.dll
前言 游戏开发的过程中,经常会出现客户端宕机的问题,这时候一个小小的dump文件可以记录当时的内存及堆栈情况,对于解决崩溃的问题有巨大的帮助,之前用VS2008的时候调试过dump文件,但是最近客户端 ...
- 无法查找或打开 pdb 文件。_Crash Dump调试:Symbol Server/Source Server、PDB原理分析
背景 UE4引擎时不时要魔改编译.可能大一点的项目是难以避免的吧 ┓( ´∀` )┏ 工程C++会自动编译,有持续集成平台做统一的编译和分发.这样可以不用每个人都编译引擎和工程C++了,代码安全性和开 ...
- 自定义VS程序异常处理及调试Dump文件(一)
1. Dump文件 1. Dump文件介绍 Dump文件(Dump File),也叫转储文件,以.DMP为文件后缀.dump文件是进程在内存中的镜像文件,通过转换然后存储成以.DMP后缀的文件.dum ...
- Linux环境崩溃生成core文件以及调试
Windows环境崩溃问题可根据vs调试工具查看,Linux同样可以查看调用堆栈的信息,只是 需要更改Linux设置,使程序崩溃时候产生core文件.然后gdb调试即可. 1产生core文件方法 产生 ...
- coredump文件的生成以及如何调试coredump文件?
生成coredump文件的相关配置 1. 首先通过 ulimit -a 命令,查看是否允许coredump文件生成; 如下图所示,core文件大小限制为0,即:不允许core文件生成 2. 使用 ul ...
- linux怎么还原bak文件,Linux restore命令:还原dump操作备份下的文件、目录或分区...
restore 命令是 dump 命令的配套命令,dump 命令是用来备份分区和数据的,而 restore 命令是用来恢复数据的. restore 命令的基本格式如下: [root@localhost ...
- 从java进程里dump出类的class文件的小工具--dumpclass
Serviceability Agent 想要查看一些被增强过的类的字节码,或者一些AOP框架的生成类,就需要dump出运行时的java进程里的字节码. 从运行的java进程里dump出运行中的类的c ...
- linux怎么还原bak文件,Linux系统restore命令:还原dump操作备份下的文件、目录或分区...
restore命令是dump命令的配套命令,dump命令是用来备份分区和数据的,而restore命令是用来恢复数据的. restore命令的基本格式如下:[root@localhost ~]# res ...
最新文章
- QTexe软件设置系统默认的图标
- (chap7 确保WEB安全的HTTPS) HTTPS加密
- 如何在 C# 中使用 FTP 上传文件
- 不止命令行!自定义VS生成事件
- 机器学习 | 早期停止法原理及Python实现
- Vs2010架构设计-层图(Layer Diagram)
- 洛谷——P1176 路径计数2
- 目标检测(三)--DPM
- 00套经典机械结构设计非标自动化SW机构3D图纸solidWorks模型库
- linux 如何添加字体
- v-charts使用-实例
- 百度应用开放平台简介
- windows下choco 安装helm
- MMDetection——GPU训练
- python scatter参数详解_Python中scatter函数参数及用法详解
- vue子元素点击事件与父元素点击事件冲突 子元素点击事件不触发
- 已解决:GET http://localhost:8080/statics/js/jquery-3.4.1.js net::ERR_ABORTED 404
- element el-transfer穿梭框的使用,自定义穿梭框的数据项
- 网络——传输层(详细版)
- DB2的HADR的搭建
热门文章
- [UESTC SC T1] 最大疯子树
- mysql5.1查询分析语句_MySQL 查询数据_mysql 查询语句_SELECT语句
- linux远程配置ssh服务,Linux远程服务之OpenSSH配置
- public 函数_C++:11友元函数、友元类
- java向数据库添加中文乱码_java向数据库中插入中文出现乱码
- CDATA不支持html,我应该在HTML5中使用(Should I use in HTML5?)
- node.val java_LeetCode——21. 合并两个有序链表(Java)
- 小菜找实习——阿里3.25场笔试第一题(矩阵数组最小差值和)
- java中spring的注解_Java代码中spring注解浅析
- 保活 进程唤醒_Android 8.0以上系统应用如何保活