1、新增文件CCreateDump.h

#pragma once
#include "stdafx.h"
#include <string>
#include <fstream>

using namespace std;
class CCreateDump
{
public:
	CCreateDump();
	~CCreateDump(void);
	static CCreateDump* Instance();
	static long __stdcall UnhandleExceptionFilter(_EXCEPTION_POINTERS* ExceptionInfo);

	void DeclarDumpFile(std::string dmpFileName = "");
private:
	static std::string    strDumpFile;
	static CCreateDump*    __instance;
};

2、CCreateDump.cpp

#include "stdafx.h"
#include <Windows.h>
#include "CCreateDump.h"
#include <DbgHelp.h>
#include <codecvt>

#pragma comment(lib,  "dbghelp.lib")

CCreateDump* CCreateDump::__instance = NULL;
std::string CCreateDump::strDumpFile = "";

CCreateDump::CCreateDump()
{
}

CCreateDump::~CCreateDump(void)
{

}

long  CCreateDump::UnhandleExceptionFilter(_EXCEPTION_POINTERS* ExceptionInfo)
{
	std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converterX;
	std::wstring dumpFile = converterX.from_bytes(strDumpFile.c_str());
	HANDLE hFile = CreateFile(dumpFile.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   dump
		BOOL   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;
	}

	return EXCEPTION_EXECUTE_HANDLER;
}

void CCreateDump::DeclarDumpFile(std::string dmpFileName)
{
	SYSTEMTIME syt;
	GetLocalTime(&syt);
	char c[MAX_PATH];
	sprintf_s(c, MAX_PATH, "%04d-%02d-%02d_%02d-%02d-%02d", syt.wYear, syt.wMonth, syt.wDay, syt.wHour, syt.wMinute, syt.wSecond);
	strDumpFile = std::string(c);
	if (!dmpFileName.empty())
	{
		strDumpFile += dmpFileName;
	}
	strDumpFile += std::string(".dmp");
	SetUnhandledExceptionFilter(UnhandleExceptionFilter);
}

CCreateDump* CCreateDump::Instance()
{
	if (__instance == NULL)
	{
		__instance = new CCreateDump;
	}
	return __instance;
}

3、main.cpp

#include <Windows.h>
#include "CCreateDump.h"

int main(void)
{
	std::ofstream ofs("test.txt", std::ios::app);
	ofs << "begin!!!" << std::endl;
	ofs.close();
	
	std::cout << "11111111111111111" << std::endl;
	std::cout << "11111111111111111" << std::endl;
	std::cout << "11111111111111111" << std::endl;
	std::cout << "11111111111111111" << std::endl;
	std::cout << "11111111111111111" << std::endl;
	CCreateDump::Instance()->DeclarDumpFile("dumpfile");
	int *p = NULL;
	std::cout << "11111111111111111" << std::endl;
	std::cout << "11111111111111111" << std::endl;
	std::cout << "11111111111111111" << std::endl;
	std::cout << "11111111111111111" << std::endl;
	std::cout << "11111111111111111" << std::endl;
	*p = 5;
	std::cout << "11111111111111111" << std::endl;
	std::cout << "11111111111111111" << std::endl;
	std::cout << "11111111111111111" << std::endl;

	std::ofstream ofs1("test.txt", std::ios::app);
	ofs1 << "end!!!" << std::endl;
	ofs1.close();

	return 0;
}

程序崩溃后,在本地exe的目录下会生成类似2020-09-24_14-06-12dumpfile.dmp的文件。

特别说明:当时直接在vs上进行运行时,不管是release还是debug模式,一运行后会直接崩溃,也不会进入异常捕获的函数,当时还以为是需要配置vs,或者是windows缺少某些系统库导致的。后来经大神提点后发现是vs调试器已经捕获导致的。直接点击exe文件运行后,生成了dump文件,完美实现生成dump。

vs使用dump文件调试方法:

1、将pdb文件、exe文件放到同一目录下
2、设置符号链接地址(pdb文件的路径):
在这里插入图片描述
在这里插入图片描述
3、附加源码路径:
项目解决方案-属性-调试源文件
在这里插入图片描述
4、点击“使用仅本机进行调试”
在这里插入图片描述
在这里插入图片描述
完成崩溃代码的定位。

注意:如果崩溃的断点注重定位到windows库的某个文件后停止了,需要下载windows库的pdb符号文件,然后再设置符号路径,将windows库的pbd文件路径加入。

windows pdb下载地址

参考博客:
https://www.cnblogs.com/swarmbees/p/5621602.html

https://blog.csdn.net/u012372584/article/details/87965913?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param

https://www.jianshu.com/p/3c5c6d571a29

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐