[Windows]_[0基础]_[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. 更新: 添加VC CRT异常捕抓. 2015-09-25
參考:
http://blog.csdn.net/limiteee/article/details/8472179
bas_dbg_report.h
#ifndef __BAS_DBG_REPORT
#define __BAS_DBG_REPORT #include "bas_exp.h" //1.能够自己改动參数,加入额外信息.
typedef void (*BASReportCallbackFunc)(const wchar_t* dump_zip_path); class LIB_BASIC BASDbgReport
{
public:
void RegisterCrashFilter(const wchar_t* dump_path,BASReportCallbackFunc func); }; #endif
bas_dbg_report.cpp
#include "basic/bas_dbg_report.h"
#include <Windows.h>
#include <DbgHelp.h> #include "basic/bas_utility_string.h"
#include "basic/bas_wrap_object.h"
#include "basic/bas_utility_zip.h" static std::wstring gDumpPath;
static std::wstring gDumpZipPath; static BASReportCallbackFunc gReportCallbackFunc = NULL; static BOOL IsDataSectionNeeded(const WCHAR* pModuleName)
{
if(pModuleName == NULL)
{
return FALSE;
} WCHAR szFileName[_MAX_FNAME] = L"";
_wsplitpath(pModuleName, NULL, NULL, szFileName, NULL); if(wcsicmp(szFileName, L"ntdll") == 0)
return TRUE; return FALSE;
} static BOOL CALLBACK MiniDumpCallback(PVOID pParam,
const PMINIDUMP_CALLBACK_INPUT pInput,
PMINIDUMP_CALLBACK_OUTPUT pOutput)
{
if(pInput == 0 || pOutput == 0)
return FALSE; switch(pInput->CallbackType)
{
case ModuleCallback:
if(pOutput->ModuleWriteFlags & ModuleWriteDataSeg)
if(!IsDataSectionNeeded(pInput->Module.FullPath))
pOutput->ModuleWriteFlags &= (~ModuleWriteDataSeg);
case IncludeModuleCallback:
case IncludeThreadCallback:
case ThreadCallback:
case ThreadExCallback:
return TRUE;
default:;
} return FALSE;
} 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; MINIDUMP_CALLBACK_INFORMATION mci;
mci.CallbackRoutine = (MINIDUMP_CALLBACK_ROUTINE)MiniDumpCallback;
mci.CallbackParam = NULL; ::MiniDumpWriteDump(::GetCurrentProcess(), ::GetCurrentProcessId(), hFile,MiniDumpNormal,&einfo, NULL, &mci);
::CloseHandle(hFile);
}
//1.压缩dmp文件和其它
char* utf8 = BASUtilityString::ConvertUnicodeToUtf8(gDumpPath.c_str());
BASWrapMalloc wm1(utf8); BASUtilityZip z;
z.AddFile(utf8);
std::string output(utf8);
output.append(".zip"); wchar_t* unicode = BASUtilityString::ConvertUtf8ToUnicode(output.c_str());
BASWrapMalloc wm2(unicode); gDumpZipPath.append(unicode); z.ToZip(output.c_str());
if(gReportCallbackFunc)
{
gReportCallbackFunc(gDumpZipPath.c_str());
}
return EXCEPTION_EXECUTE_HANDLER;
} static LPTOP_LEVEL_EXCEPTION_FILTER WINAPI MyDummySetUnhandledExceptionFilter(
LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter)
{
return NULL;
} static BOOL PreventSetUnhandledExceptionFilter()
{
HMODULE hKernel32 = LoadLibrary(L"kernel32.dll");
if (hKernel32 == NULL) return FALSE;
void *pOrgEntry = GetProcAddress(hKernel32, "SetUnhandledExceptionFilter");
if(pOrgEntry == NULL) return FALSE;
unsigned char newJump[ 100 ];
DWORD dwOrgEntryAddr = (DWORD) pOrgEntry;
dwOrgEntryAddr += 5; // add 5 for 5 op-codes for jmp far
void *pNewFunc = &MyDummySetUnhandledExceptionFilter;
DWORD dwNewEntryAddr = (DWORD) pNewFunc;
DWORD dwRelativeAddr = dwNewEntryAddr - dwOrgEntryAddr; newJump[ 0 ] = 0xE9; // JMP absolute
memcpy(&newJump[ 1 ], &dwRelativeAddr, sizeof(pNewFunc));
SIZE_T bytesWritten;
BOOL bRet = WriteProcessMemory(GetCurrentProcess(),
pOrgEntry, newJump, sizeof(pNewFunc) + 1, &bytesWritten);
return bRet;
} void BASDbgReport::RegisterCrashFilter(const wchar_t* dump_path,BASReportCallbackFunc func)
{
#ifndef _DEBUG
gDumpPath.append(dump_path);
gReportCallbackFunc = func;
SetUnhandledExceptionFilter(TopLevelUnhandledExceptionFilter);
//BOOL bRet = PreventSetUnhandledExceptionFilter(); //这个部分系统会崩溃,临时不使用.
#endif
}
[Windows]_[0基础]_[Release程序的崩溃报告minidump解决方式]的更多相关文章
- [Zlib]_[0基础]_[使用zlib库压缩文件]
场景: 1. WIndows上没找到系统提供的win32 api来生成zip压缩文件, 有知道的大牛麻烦留个言. 2. zlib比較经常使用,编译也方便,使用它来做压缩吧. MacOSX平台默认支持z ...
- [libcurl]_[0基础]_[使用libcurl下载大文件]
场景: 1. 在Windows编程时, 下载http页面(html,xml)能够使用winhttp库,可是并非非常下载文件,由于会失败. 由此引出了WinINet库,无奈这个库的稳定性比較低,使用样例 ...
- [wxWidgets]_[0基础]_[经常更新进度条程序]
场景: 1. 非常根据程序的进展需要处理业务,以更新进度条,进度条的目的是为了让用户知道业务流程的进度.一个进度条程序更友好,让用户知道在程序执行.不是没有反应. 2. 现在更新见过这两种方法的进展. ...
- [Windows]_[0基础]_[使用命令行工具dumpbin分析文件]
dumpbin(vs拥有) 1. 出口lib函数符号文件(symbols) dumpbin /exports zlib1.lib Microsoft (R) COFF/PE Dumper Versio ...
- [C/C++标准库]_[0基础]_[交集和补集]
场景: 1. 计算std::vector A和 std::vector B里的同样的元素, 用于保留不删除. 2. 计算std::vector A和 std::vector B里各自的补集, 用于删除 ...
- [网络]_[0基础]_[使用putty备份远程数据]
场景: 1. putty是windows上訪问linux服务的免费client之中的一个.用它来ssh到远程server备份数据是常见的做法(在没做好自己主动备份机制前), 通过putty界面尽管也不 ...
- [wxWidgets]_[0基础]_[不常见但有用的类wxStandardPaths]
场景: 1.wxStandardPaths 用来获取各种系统路径.能够用于存放app的配置数据.比方文档文件夹,appData等. 代码: #include "wx/wxprec.h&q ...
- [C/C++11语法]_[0基础]_[lamba 表达式介绍]
场景 lambda 表达式在非常多语言里都有一席之地,由于它的原因,能够在函数里高速定义一个便携的函数,或者在函数參数里直接高速构造和传递. 它能够说是匿名函数对象,一般仅仅适用于某个函数内,仅仅做暂 ...
- [C/C++标准库]_[0基础]_[使用fstream合并文本文件]
场景: 1. 就是合并文本文件,而且从第2个文件起不要合并第一行. 2. 多加了一个功能,就是支持2个以上的文件合并. 3. 问题: http://ask.csdn.net/questions/192 ...
随机推荐
- Windows(7/8/10)搭建Elasticsearch 6.x版本
今天公司用到了Elasticsearch ,记录一下单机版搭建的流程. 首先我们来看下什么是Elasticsearch : ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分 ...
- System.Data.SqlClient.SqlException: 在向服务器发送请求时发生传输级错误。 (provider: TCP 提供程序, error: 0 - 远程主机强迫关闭了一个现有的连接。) .
今天使用sql server 2008 R2管理器,进行SQL查询时,频率非常高的报错: System.Data.SqlClient.SqlException: 在向服务器发送请求时发生传输级错误. ...
- Java Controller下兼容xls和xlsx且可识别合并单元格的excel导入功能
1.工具类,读取单元格数据的时候,如果当前单元格是合并单元格,会自动读取合并单元格的值 package com.shjh.core.util; import java.io.IOException; ...
- 实现div毛玻璃背景
毛玻璃效果 ios里毛玻璃效果的使用非常多,本文介绍一个实现div毛玻璃背景的方法 CSS3 Filter CSS3的Filter主要用在图像的特效处理上,默认值为none,还有以下备选项: 1. ...
- java与javascript之间json格式数据互转
javascript中对象与字符串的互转 对象转为字符串:通过JSON.encode方法,这个是json.js里面的方法,引入到当前文件就可以了. 字符串转换为对象:①使用JSON.decode方法, ...
- JAVA趣味逻辑算法
/**已知4位同学中的一位数学考了100分,当小李询问这4位是谁考了100分时,4个人的回答如下: A说:不是我. B说:是C C说:是D. D说:他胡说. 已知三个人说的是真话,一个人说的是假话.现 ...
- Twisted web开发教程
最近在网上看到一篇twisted web开发文章,将它实践了一下,twisted 提供基本的url路由 和 控制器,模板与模型需要外部扩展 1.目录浏览 2.get请求 3.url路由 4.接受带参数 ...
- (转) Quartz学习——SSMM(Spring+SpringMVC+Mybatis+Mysql)和Quartz集成详解(四)
http://blog.csdn.net/u010648555/article/details/60767633 当任何时候觉你得难受了,其实你的大脑是在进化,当任何时候你觉得轻松,其实都在使用以前的 ...
- zxing 生成条形码
private Bitmap Out1DImg() { // 1.设置条形码规格 EncodingOptions encodeOption = new EncodingOptions(); encod ...
- csrf漏洞利用
low csrf(cross-site-request forgery),跨站请求伪造. 测试网站 --http://localhost/vulnerability/csrf 修改密码,点击chang ...