交给客户的软件奔溃了怎么办?

我们不能再客户电脑上安装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就会运行起来。

点击画圈的部分就可以定位到代码出错的位置啦。

qt5.9.0 msvc2015优雅的崩溃:dumpfile的更多相关文章

  1. QT5.8.0+MSVC2015安装以及环境配置(不需要安装VS2015)

    原文:QT5.8.0+MSVC2015安装以及环境配置(不需要安装VS2015) 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/snow_rain_ ...

  2. Win7+Qt5.6.0(64位)+msvc2015编译器 环境配置

    根据“Qt简介,Qt 5.6.0-VS2015 版本安装配置图文教程”安装第二套IDE,使用Qt官方的集成开发环境 QtCreator + 微软的WinDbg调试器(内含命令行调试器为CDB)的组合. ...

  3. 使用Qt5.7.0 VS2015版本生成兼容XP的可执行程序 good(从VS2012 update1开始支持xp和c++11)

    一.直接使用VS2012/VS2013/VS2015生成XP兼容的可执行程序 Visual Studio刚发布时没打补丁,称为RTM版,之后会陆续发布补丁,进行bug修复和功能增强.VS2010及之前 ...

  4. 使用Qt5.7.0 VS2015版本生成兼容XP的可执行程序

    版权声明:本文为灿哥哥http://blog.csdn.net/caoshangpa原创文章,转载请标明出处. 一.直接使用VS2012/VS2013/VS2015生成XP兼容的可执行程序 Visua ...

  5. VS2010+Qt5.4.0 环境搭建(离线安装)

    原创作者:http://blog.csdn.net/solomon1558/article/details/44084969 前言 因项目需要Qt开发GUI,我根据网上资料及自己的经验整理了搭建vs2 ...

  6. qt5.4.0编译错误

    error1: 进程"C:\Qt\Qt5.4.0\Tools\QtCreator\bin\jom.exe"退出,退出代码 2 solution:去工具->选项->构建和 ...

  7. Qt5.7.0配置选项(configure非常详细的参数)

    configure是一个命令行工具,用于配置Qt编译到指定平台.configure必须运行于Qt源码根目录.当运行configure时,编译源码使用的是所选工具链中的make工具. 一.源码目录.编译 ...

  8. VS2013编译Qt5.6.0静态库

    获取qt5.6.0源码包 直接去www.qt.io下载就好了,这里就不详细说了. 这里是我已经编译好的** 链接:http://pan.baidu.com/s/1pLb6wVT 密码: ak7y ** ...

  9. VS2015编译Qt5.7.0生成支持XP的静态库(很不错)

    一.编译工具 1.VS2015 编译Qt5.7.0的所需VS版本:Visual Studio 2013 (Update1)或Visual Studio 2015 (Update2).因为Update补 ...

随机推荐

  1. 在iOS下-input[disabled] 颜色变浅兼容&& input[readonly]仍可获取焦点解决方法

    目标:在写input输入框时,想让其只读不写. 环境:在iPhone上 本来用的时readonly,可是readonly,居然可以获取焦点,不能弹出键盘:安卓手机完全木有问题,所以去用了disable ...

  2. 从零开始的JAVA(1).输入

    理一遍JAVA的输入和输出,跟C语言还是有点不用的,虽然以前学过一点.不过好像忘的一干二净了哈哈.从头来一遍把,这次跟着翁恺老师GOGO 1.输出语句:System.out.println();--快 ...

  3. std::ref和std::cref使用(转载)

    转载于:https://blog.csdn.net/lmb1612977696/article/details/81543802 std::ref和std::cref 解释: std::ref 用于包 ...

  4. Dubbo服务暴露分析

    Dubbo的服务暴露是一个重要的特性,了解其机制很重要.之前有很多人写了有关的源代码分析,在本文中不再重新分析.官方文档中的一篇写的就很好,本文主要是有关内容进行补充与总结. 传送门:服务导出 为什么 ...

  5. jQuery---第一部分复习

    jquery: 简单.粗暴    jq和js的关系   js是什么? js是一门编程语言   jq仅仅是基于js的一个库,jq可理解为就是开发js的一个工具.          概念   1. 为什么 ...

  6. 844. 走迷宫(bfs模板)

    给定一个n*m的二维整数数组,用来表示一个迷宫,数组中只包含0或1,其中0表示可以走的路,1表示不可通过的墙壁. 最初,有一个人位于左上角(1, 1)处,已知该人每次可以向上.下.左.右任意一个方向移 ...

  7. 一道CTF针对XXE漏洞的练习

    题目链接:http://web.jarvisoj.com:9882/ 目的很明确获取/home/ctf/flag.txt的内容 一般读取目标机的本地文件都会用到file协议. 思路: 那么思路一:文件 ...

  8. numpy小结(一)

    1.np.zero(10)     创建一个包含10个元素的一维数组 np.ones((10,10))     创建一个包含10*10个元素1的二维数组 2.np.arange(10,50)      ...

  9. 占位 SC

    占位 SC include: SC404 SC405

  10. TCL namespace

    命名空间可从Tcl 8.0版开始使用.引入命名空间之前,有一个全局范围.现在有了命名空间,我们可以分区全局范围. 创建命名空间: 结果:33 嵌套命名空间: 结果: test1 test2 导入命名空 ...