如何将崩溃信息整合到应用程序-基础知识
--nana_aoe
注明:该文档原创,转载请注明出处:http://blog.csdn.net/nana_aoe/article/details/15026975
0简介
如果你是一个应用软件开发者,你一定遇到过程序崩溃(内存访问越界,使用空指针,等等)。假如该场景并没有发生在你的开发环境,而是发生在客户方。可能你需要使用者给你描述一个下崩溃的情景,例如:有没有截屏,提示什么错误等等,关键问题在于用户可能不是一个搞技术的,他不能给你提供更多的有信息,只能说程序崩掉了。这时,可能就束手无策了。
这篇笔记就记录了在程序崩溃时,将崩溃的信息(崩溃当时的堆栈、线程等等信息)保存下来。
这里使用的是一个叫做“CrashRpt”的开源库,这个库十分强大,支持Visual C++ .Net2003、2005、2008、2010甚至C++Express,无论你的程序是基于WinAPI、ATL、MFC都可以使用。下面我会以控制台应用程序为例介绍一下CrashRpt的使用。
1下载CrashRpt库
官方下载地址:http://code.google.com/p/crashrpt/
网盘下载地址:http://wx180223.7958.com/down_10050422.html
备注:
官方下载实在慢,终于下载完了还解压失败,花了2个小时才搞下来,为了方便大家使用,我上传到网盘了(版本crashrpt v1.4.2),如果使用最新版,推荐到官方下载。
2介绍CrahRpt库(以CrashRpt v1.4.2为例)
看着文件夹和文件很多,其实实际使用的并不多。介绍一下我们要使用的。
/bin子文件夹:
CrashRpt1402.dll(核心文件)封装了所有CrashRpt的API接口
CrashSender1402.exe(核心文件)发送CrashRpt的exe
dbghelp.dll(辅助文件)
crashrpt_lang.ini (辅助文件)崩溃信息简述中的语言种类。
在老版本中是没有dbghelp.dll、crashrpt_lang.ini的,但是在新版本中,需要加上这两个文件才能运行。
/include子文件夹
这个就不用说,核心文件CrashRpt.h,函数声明嘛。
以上我是基于使用说的,如果想详细分析CrashRpt,请自行摸索。
3 实际应用
首先说明一下,我们使用第2部分介绍的几个文件。
下面说明一下工程配置:(vs2010)
首先将CrashRpt的头文件引进来,两种方法:
1) 将使用的CrashRpt直接放到你工程的头文件夹内。(不推荐)
2) 将使用的CrashRpt路径包含到工程中。(推荐,将不同功能的头文件分开好处还是有的,尤其是使用第三方的)
在<项目>-><属性>-><配置属性>-><C/C++>-><常规>-><附加包含目录>添加$(SolutionDir)include,我将整个库include文件夹放到了.sln目录下。
在<项目>-><属性>-><配置属性>-><链接器>-><常规>-><附加库目录>添加
$(SolutionDir)lib,我将整个lib文件夹放在.sln目录下
在<项目>-><属性>-><配置属性>-><链接器>-><输入>-><附加依赖项>添加CrashRpt1402.lib
好了,O了。
在使用时,在程序刚开始时,将CrashRpt一初始化,崩溃的时候会自动调用的。
差点忘了,要把/bin目录里的几个文件(就是第二步介绍的)拷贝到你的可执行程序目录下
代码:
// ttt.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "CrashRpt.h"
#include <string>
using std::string;
int CrashInit()
{
CR_INSTALL_INFO info;
memset(&info, 0, sizeof(CR_INSTALL_INFO));
info.cb = sizeof(CR_INSTALL_INFO);
info.pszAppName = _T("SimpleAp"); // Define application name.
info.pszAppVersion = _T("1.0.0"); // Define application version.
// URL for sending error reports over HTTP.
info.pszUrl = _T("http://someserver.com/crashrpt.php");
// Install all available exception handlers.
info.dwFlags |= CR_INST_ALL_POSSIBLE_HANDLERS;
// Use binary encoding for HTTP uploads (recommended).
info.dwFlags |= CR_INST_HTTP_BINARY_ENCODING;
// Provide privacy policy URL
info.pszPrivacyPolicyURL = _T("http://someserver.com/privacy.html");
info.uMiniDumpType = MiniDumpWithFullMemory;
info.pszErrorReportSaveDir = _T("DefaultSaveFolder");
int nResult = crInstall(&info);
if(nResult!=0)
{
TCHAR buff[256];
crGetLastErrorMsg(buff, 256);
MessageBox(NULL, buff, _T("crInstall error"), MB_OK);
return 1;
}
// Take screenshot of the app window at the moment of crash
crAddScreenshot2(CR_AS_MAIN_WINDOW|CR_AS_USE_JPEG_FORMAT, 95);
BOOL bRun;
BOOL bExit=FALSE;
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
if(0 != CrashInit())
printf("CrashRpt Init Failed!\n");
int *p=0;
*p =0;
printf("Hello world!\n");
return 0;
}
源码下载:
http://wx180223.7958.com/down_10050407.html
这就是我使用空指针崩溃产生的文件
其中内存镜像文件就是crashdump.dmp文件了,如果想进一步了解,请参考:
以上均为个人见解,欢迎讨论,有问题请留言或邮件nana_aoe@126.com
2013-11-10