[C++] 程序崩溃时输出Dmp文件(崩溃转储)

捕获未经处理的异常

目的

  程序在异常捕获中难免会遇到未经捕获的异常,因此要在最上级对未抓取异常进行处理,包括保存用户文件及输出Dmp文件,Dmp文件可以帮助开发人员快速定位异常所在具体工具可以利用VisualStudio或者Windbg工具来跟踪定位异常抛出语句。
  举个例子,office系列Word大家都用过,如果遇到崩溃退出,你所敲过的文字office是会给你保存下来的不会丢失,这就是要讲的内容。当然现在office很少出现崩溃了

关键API

	SetUnhandledExceptionFilter();

具体操作

LONG WINAPI UnhandledExceptionFilter(PEXCEPTION_POINTERS pExInfo)
{
	//未经处理会跳转到此处
}
SetUnhandledExceptionFilter(UnhandledExceptionFilter);

完整代码输出Dump文件

头文件内容

#pragma once
class ExceptionDmp
{
public:
   ExceptionDmp();
   ~ExceptionDmp();
};

源文件内容

LONG WINAPI UnhandledExceptionFilter(PEXCEPTION_POINTERS pExInfo)
{
	TCHAR dmp_path[MAX_PATH];
	::GetTempPath(_countof(dmp_path), dmp_path);
	SYSTEMTIME tm;
	GetLocalTime(&tm);//获取时间
	TCHAR file_name[128];
	_stprintf_s(file_name, L"%spbim%d-%02d-%02d-%02d-%02d-%02d.dmp", dmp_path,
		tm.wYear, tm.wMonth, tm.wDay, tm.wHour, tm.wMinute, tm.wSecond);//设置dmp文件名称
	HANDLE hFile = CreateFile(file_name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
		FILE_ATTRIBUTE_NORMAL, NULL);
	if (hFile != INVALID_HANDLE_VALUE)
	{
		MINIDUMP_EXCEPTION_INFORMATION info;//构造dmp异常数据结构
		info.ThreadId = GetCurrentThreadId();
		info.ClientPointers = FALSE;
		info.ExceptionPointers = pExInfo;
		MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile,
			(MINIDUMP_TYPE)MiniDumpNormal, &info, NULL, NULL);//写dmp文件
		CloseHandle(hFile);

		const TCHAR *fmt =
		{
			L"遇到问题需要关闭,您的数据有可能丢失,\n\n"
			L"我们对此引起的不便表示抱歉;请将\n\n"
			L"\"%s\"\n\n"
			L"发送给我们以便快速查找问题之所在,谢谢。\n\n"
			L"邮箱:************\n\n"
			L"电话:***-****-***"
		};
		TCHAR msg[400];
		_stprintf_s(msg, fmt, file_name);
		MessageBox(NULL, msg, L"程序异常报告", MB_ICONERROR | MB_SYSTEMMODAL);
	}
	else
	{
		TCHAR info[300] = { L"fail to create dump file:" };
		_tcscat(info, file_name);
		MessageBox(NULL, info, L"dump", MB_ICONERROR | MB_SYSTEMMODAL);
	}
	return EXCEPTION_EXECUTE_HANDLER;
}
ExceptionDmp::ExceptionDmp()
{
	SetUnhandledExceptionFilter(UnhandledExceptionFilter);
}
static ExceptionDmp s_ExceptionDmp;

ExceptionDmp::~ExceptionDmp()
{
}

注册入口由静态堆变量 s_ExceptionDmp 触发构造函数进行API调用;

关键步骤加了注释,教程到此结束。

请记住崩溃转储的价值往往比1000个甚至更多的bug报告更有意义

猜你喜欢

转载自blog.csdn.net/m0_38125278/article/details/85676318