qt5.9.0 msvc2015优雅的崩溃:dumpfile
2024-09-06 23:05:14
交给客户的软件奔溃了怎么办?
我们不能再客户电脑上安装vs,也不想傻傻的用log来猜测出错的地方。
利用Dbghelp可以解决这一问题。
首先是vs生成release版本的时候需要同时生成pdb文件,这里以vs2015为例:
https://blog.csdn.net/yhc166188/article/details/80695317
基本设置流程如下:
1、项目->属性->C/C++->General->Debug Information Format->Program Database for Edit & Continue (/ZI)
2、项目->属性->C/C++->Optimization->Optimization->Disabled(/Od)
3、项目->属性->Linker->Debugging->Generate Debug Info->Yes(/DEBUG)
此时,再编译软件,就会同时生成.pdb文件。
回到项目中来,我们还需要添加一点代码,使得程序优雅的奔溃。
新建一个dumpfile.h文件,将以下代码拷贝进去
#pragma once
#include <windows.h>
#include < Dbghelp.h>
#include <iostream>
#include <vector>
#include <tchar.h>
using namespace std; #pragma comment(lib, "Dbghelp.lib") namespace NSDumpFile
{
void CreateDumpFile(LPCWSTR lpstrDumpFilePathName, EXCEPTION_POINTERS *pException)
{
// 创建Dump文件
//
HANDLE hDumpFile = CreateFile(lpstrDumpFilePathName, GENERIC_WRITE, , NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); // Dump信息
//
MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
dumpInfo.ExceptionPointers = pException;
dumpInfo.ThreadId = GetCurrentThreadId();
dumpInfo.ClientPointers = TRUE; // 写入Dump文件内容
//
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpNormal, &dumpInfo, NULL, NULL); CloseHandle(hDumpFile);
} LPTOP_LEVEL_EXCEPTION_FILTER WINAPI MyDummySetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter)
{
return NULL;
} BOOL PreventSetUnhandledExceptionFilter()
{
HMODULE hKernel32 = LoadLibrary(_T("kernel32.dll"));
if (hKernel32 == NULL)
return FALSE; void *pOrgEntry = GetProcAddress(hKernel32, "SetUnhandledExceptionFilter");
if (pOrgEntry == NULL)
return FALSE; unsigned char newJump[];
DWORD dwOrgEntryAddr = (DWORD)pOrgEntry;
dwOrgEntryAddr += ; // add 5 for 5 op-codes for jmp far void *pNewFunc = &MyDummySetUnhandledExceptionFilter;
DWORD dwNewEntryAddr = (DWORD)pNewFunc;
DWORD dwRelativeAddr = dwNewEntryAddr - dwOrgEntryAddr; newJump[] = 0xE9; // JMP absolute
memcpy(&newJump[], &dwRelativeAddr, sizeof(pNewFunc));
SIZE_T bytesWritten;
BOOL bRet = WriteProcessMemory(GetCurrentProcess(), pOrgEntry, newJump, sizeof(pNewFunc) + , &bytesWritten);
return bRet;
} LONG WINAPI UnhandledExceptionFilterEx(struct _EXCEPTION_POINTERS *pException)
{
TCHAR szMbsFile[MAX_PATH] = { };
::GetModuleFileName(NULL, szMbsFile, MAX_PATH);
TCHAR* pFind = _tcsrchr(szMbsFile, '\\');
if (pFind)
{
*(pFind + ) = ;
_tcscat(szMbsFile, _T("CrashDumpFile.dmp"));
CreateDumpFile(szMbsFile, pException);
} // TODO: MiniDumpWriteDump
FatalAppExit(-, _T("Fatal Error"));
return EXCEPTION_CONTINUE_SEARCH;
} void RunCrashHandler()
{
SetUnhandledExceptionFilter(UnhandledExceptionFilterEx);
PreventSetUnhandledExceptionFilter();
}
}; #define DeclareDumpFile() NSDumpFile::RunCrashHandler();
接着,在全局类(例如main文件,或者QMainWindow派生类)里面添加头文件dumpfile.h,然后在构造函数或者全局添加宏:
DeclareDumpFile()即可。
#include "StockTradeByTdxMulti.h"
#include <QtWidgets/QApplication>
#include <QFile>
#include "dumpfile.h" int main(int argc, char *argv[])
{
QApplication a(argc, argv);
DeclareDumpFile()
StockTradeByTdxMulti w;
w.show();
return a.exec();
}
如果exe出错了,就会生成CrashDumpFile.dmp文件,当然你也可以改成你希望的名字。
最后,你从客户那边拿到CrashDumpFile.dmp,放到上面说的.pdb文件所在文件夹。双击运行CrashDumpFile.dmp,vs就会运行起来。
点击画圈的部分就可以定位到代码出错的位置啦。
最新文章
- 字符串 HDU 1039
- Codeforces Round #238 (Div. 2) D. Toy Sum(想法题)
- AC日记——将字符串中的小写字母换成大写字母 openjudge 1.7 13
- 多条查询sql语句返回多表数据集
- iOS7 UIKit动力学-碰撞特性UICollisionBehavior 上
- Animate.css让添加CSS动画像喝水一样容易
- 配置好postfix邮件服务器之后就可以使用它来发送邮件了
- Java8 日期/时间(Date Time)使用简介
- 有关CSS的overflow和border-radius的那些事,你的圆角被覆盖了吗?
- Python:Day25 成员修饰符、特殊成员、反射、单例
- CANOE入门(二)
- keepalived-1
- [转]java.util.Date和java.sql.Date转换
- 如何通过DataGridView 实现单元格合并和二维表头
- 正则 js分转元带千分符号
- NY891 区间选点 找点
- swift - UIStepper的用法
- 从零开始的Python学习Episode 2——运算符与while循环
- Java 输入参数并求和
- h5获取摄像头拍照功能
热门文章
- Unable to execute command or shell on remote system: Failed to Execute process
- Docker最全教程——从理论到实战(十七)
- BZOJ 2467: [中山市选2010]生成树
- ASP.NET MVC模块化开发——动态挂载外部项目
- [CodeIgniter4]讲解-加载静态页
- 前端:将网站打造成单页面应用SPA
- 【python&;pycharm的安装使用】
- Java基础--数组(Arrays)
- opencv图像坐标
- .netcore 3.1高性能微服务架构:加入swagger接口文档