[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
}
时间: 2024-10-21 12:23:17

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

[MinGW]_[初级]_[64位的windres如何编译32位的链接文件]

场景: 1.   MinGW(TDM)出了64位的gcc,4.8.1,64位对编译64位的程序非常友好,但是对编译32位程序就需要做额外的工作了. 2.  比如用windres编译manifest,64位环境下默认是不行的,带configure或makefile的即使加了-m32都不会自动对windres设置为编译32位的. 这里就需要在configure或make增加一些参数了. ./configure RCFLAGS="--output-format=coff --target=pe-i38

[Android]_[初级]_[Android开发环境配置入门(Windows)]

场景: 1. 突然接到android的开发任务时如何配置android开发环境? 2. 现在的android studio是基于idea的,在我的电脑上运行奇慢和卡.而且有遗留eclipse项目,大部分教程都是基于eclipse的. 所以入门来说adt开发android程序比较适合. 3. 如果有深入研究的话,直接用其他ide配合build sdk开发也不是不行. 第一步. 配置ADT的Android开发环境. 注意1: 如果要下载所有的Android API,会耗费很大空间,所以选择比较特殊的

[Windows]_[初级]_[创建独立子进程和读取子进程的输出]

场景: 1.  有一些外部工具命令需要通过程序调用,比如启动服务器或者使用网络命令获取输出. 2.  使用了匿名管道CreatePipe获取子进程输出. 参考: 1.  MSDN的主题<Creating a Child Process with Redirected Input and Output>. 2.  <Windows核心编程>进程章节. 代码: #include "test_shellrun.h" #include <stdlib.h>

[C/C++标准库]_[初级]_[过滤Windows文件名中的非法字符]

场景: 1. 通常生成文件时需要一个文件名,而生成文件名的方式可能是通过用户输入的字符,但是有些字符在windows上是不能作为文件名的,强行创建这类文件会失败. 2.一般可以通过正则表达式替换所有的非法字符,这里实现的是C++98 template(模板)方式的替换无效字符,std::string,std::wstring. 基本上windows上和字符串打交道都离不开wstring. 函数: template<class T> void FilterInvalidFileNameChar(

[Cocoa]_[初级]_[NSTableView--数据操作和表格操作要注意的问题]

1.首先在MainMenu.lib文件里面创建一个NSTableView,在界面上显示一个表格出来,并对表格进行设置. 2.创建文件TableViewDelegate.h和TableViewDelegate.m(文件内容如下文件所示).并在MainMenu.lib文件中创建一个Object(从窗口右边选中Object,拉到在Window中的对话框中),命名:TableViewDelegate. 3.设置代理:tableView 进行设置,和图片中的Table View进行连接. staticFi

[项目管理]_[初级]_[TortoiseSVN的使用入门]

Svn 概述: svn是版本控制工具,简单来说它的功能就是通过差异算法来记录你每次提交的文件差异来存储的,版本控制工具的好处是你可以代码出问题时回退到某个时间点的代码,或对比最新和本机代码看有哪些变化等,对排除程序bug,代码审查,保存稳定版本程序是作用很大的. 1. Svn主要有几个操作需要会用,客户端 Windows: TortoiseSVN MacOSX:   SvnX 命令行:     svn(通用) 创建资源库(Create respository) 1.资源库是存放源代码的地方,sv

[libcurl]_[初级]_[使用libcurl下载大文件]

场景: 1. 在Windows编程时, 下载http页面(html,xml)可以使用winhttp库,但是并不是很下载文件,因为会失败. 由此引出了WinINet库,无奈这个库的稳定性比较低,使用例子又少, 下载大文件时经常是不完整,可查找的资料很少或者是没有特殊情况的解决办法. 2. 我的原则是如果系统有自带的就用系统的,但是 WinINet 要掌握需要花不少时间. 时间因素考虑到了libcurl. 3. libcurl支持ftp,http等协议的文件读取,还能自动获取文件大小, 最重要的是不

[ATL/WTL]_[初级]_[拖放文件到窗口]

场景: 1. 软件需要支持从桌面拖动文件到软件里,避免从文件打开窗口选择文件,这样效率快很多,这时就需要窗口支持拖放技术. drag and drop. 2. 软件需要复制文件到远程或设备里,支持拖放的话就很方便. 两种方案: 1. 如果是Windows 窗口程序, 可以使用监听WM_DROPFILES 消息来实现, 这里讲解第一种, 比较方便. http://blog.csdn.net/laogaoav/article/details/9152181 2. 如果不想监听 WM_DROPFILE

[WTL/ATL]_[初级]_[如何使用GetOpenFileName多选文件-根据文件名长度计算lpstrFile长度]

场景: 1. 使用GetOpenFileName 时, 需要预先自定义lpstrFile的长度比如,buf[1024], 但是如果选择的文件过多怎么办?总不能创建一个超大的内存空间吧, 如果选择少时又浪费内存. 2. 微软的MSDN的坏处就是不提供实际的例子,而在别的地方提供,难道他们没遇到这类普通的问题? 3. 这里stackoverflow提供了一个微软使用lpfnHook 的例子来解决这个问题,这个例子对于unicode是有问题的,计算长度没有x2. 这个bug困扰了我半天. 找这个解决方