[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 ...
随机推荐
- BZOJ 2001 线段树+LCT (TLE)
同是O(nlog^2n)怎么常数差距就这么大呢,,, 同是LCT 怎么我的和Po姐姐的常数差距就这么大呢 我绝对是脑子被驴踢了才写这个垃圾算法 //By SiriusRen #include < ...
- [转]asp.net MVC 常见安全问题及解决方案
本文转自:http://www.cnblogs.com/Jessy/p/3539564.html asp.net MVC 常见安全问题及解决方案 一.CSRF (Cross-site request ...
- Android Studio查看CPU使用率。
进入AS自带的CMD,依次输入: (1)进入Android Atudio安卓的目录: 1.H: 2.cd AndroidStudio\sdk\platform-tools (2)adb shell ( ...
- 我的liunx开发环境的配置之路
相信有不少人和我一样,虽然是做纯linux开发,但并不排斥windows,并且喜欢在windows下面的使用各种好用的工具来让linux的编程工作变得更加方便.实际上每一个系统都有他的过人支持,win ...
- 13、scala模式匹配
1.模式匹配的基础语法 2.对类型进行模式匹配 3.对Array和List的元素进行模式匹配 4.case class与模式匹配 5.Option与模式匹配 1.模式匹配的基础语法 Scala提供了m ...
- 【sqli-labs】 less50 GET -Error based -Order By Clause -numeric -Stacked injection(GET型基于错误的整型Order By从句堆叠注入)
报错没有关闭,直接可以用UpdateXml函数 http://192.168.136.128/sqli-labs-master/Less-50/?sort=1 and UpdateXml(1,conc ...
- @viewChild
https://www.cnblogs.com/mttcug/p/8004359.html
- ngFor 循环带索引
*ngFor="let item of userList,let i = index" 或者 *ngFor="let item of userList index a ...
- 51nod1049 最大子段和【动态规划】
N个整数组成的序列a[1],a[2],a[3],-,a[n],求该序列如a[i]+a[i+1]+-+a[j]的连续子段和的最大值.当所给的整数均为负数时和为0. 例如:-2,11,-4,13,-5,- ...
- [luogu1485 HNOI2009] 有趣的数列 (组合数学 卡特兰数)
传送门 Solution 卡特兰数 排队问题的简单变化 答案为\(C_{2n}^n \pmod p\) 由于没有逆元,只好用分解质因数,易证可以整除 Code //By Menteur_Hxy #in ...