首页 > 代码库 > [Windows]_[初级]_[Release程序的崩溃报告minidump解决方案]

[Windows]_[初级]_[Release程序的崩溃报告minidump解决方案]


场景:

1. Release的程序崩溃时,崩溃报告可以让开发人员查明代码哪里出了问题,用处大大的。

2. 只有用VS的编译器才支持,所以MinGW就无缘了。

3. 使用了未处理异常过滤处理函数.

4. 生成的.dmp文件用zlib库压缩, 用到以下的ZipHelper类,编译时还是需要zlib库和dbghelp.lib

http://blog.csdn.net/infoworld/article/details/41290969


5. 使用方式就是把DbgReport作为app类的成员变量,或者文件范围的全局变量初始化后,在程序运行开始前调用

RegisterCrashFilter

6. 有帮助的帮忙顶下或留个言.


dbg_report.h

#ifndef __DBG_REPORT
#define __DBG_REPORT

#include <string>

//1.可以自己修改参数,添加额外信息.
typedef void (*ReportCallbackFunc)(const wchar_t* dump_zip_path);

class DbgReport
{
public:
	DbgReport(){}
	~DbgReport(){}

	void RegisterCrashFilter(const wchar_t* dump_path,ReportCallbackFunc func);

};

#endif

dbg_report.cpp

#include "dbg_report.h"
#include <Windows.h>
#include <DbgHelp.h>

#include "zip_helper.h"

static std::wstring gDumpPath;
static std::wstring gDumpZipPath;

static ReportCallbackFunc gReportCallbackFunc = NULL;

static char* QXUnicode2Utf8(const wchar_t* unicode)  
{  
    int len;  
    len = WideCharToMultiByte(CP_UTF8, 0, unicode, -1, NULL, 0, NULL, NULL);  
    char *szUtf8 = (char*)malloc(len + 1);  
    memset(szUtf8, 0, len + 1);  
    WideCharToMultiByte(CP_UTF8, 0, unicode, -1, szUtf8, len, NULL,NULL);  
    return szUtf8;  
}

static wchar_t* QXUtf82Unicode(const char* utf)  
{  
	if(!utf || !strlen(utf))  
	{  
		return NULL;  
	}  
	int dwUnicodeLen = MultiByteToWideChar(CP_UTF8,0,utf,-1,NULL,0);  
	size_t num = dwUnicodeLen*sizeof(wchar_t);  
	wchar_t *pwText = (wchar_t*)malloc(num);  
	memset(pwText,0,num);  
	MultiByteToWideChar(CP_UTF8,0,utf,-1,pwText,dwUnicodeLen);  
	return pwText;  
} 

static LONG WINAPI TopLevelUnhandledExceptionFilter(PEXCEPTION_POINTERS pExInfo)
{
	HANDLE hFile = ::CreateFile( gDumpPath.c_str(), 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);
	}
	//1.压缩dmp文件和其他
	char* utf8 = QXUnicode2Utf8(gDumpPath.c_str());
	ZipHelper z;
	z.AddFile(utf8);
	std::string output(utf8);
	output.append(".zip");

	wchar_t* unicode = QXUtf82Unicode(output.c_str());
	gDumpZipPath.append(unicode);

	z.ToZip(output.c_str());
	free(utf8);
	free(unicode);
	if(gReportCallbackFunc)
	{
		gReportCallbackFunc(gDumpZipPath.c_str());
	}
	return EXCEPTION_EXECUTE_HANDLER;
}

void DbgReport::RegisterCrashFilter(const wchar_t* dump_path,ReportCallbackFunc func)
{
#ifndef _DEBUG
	gDumpPath.append(dump_path);
	gReportCallbackFunc = func;
	SetUnhandledExceptionFilter(TopLevelUnhandledExceptionFilter);
#endif
}




[Windows]_[初级]_[Release程序的崩溃报告minidump解决方案]