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

我们不能再客户电脑上安装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. C语言 小技巧函数方法总结

    1.使用^(异或) 不引入第三变量交换两个变量的值. /* 交换 int a 和 int b 的值*/ #include <stdio.h> int main(int argc, char ...

  2. 小白月赛22 B : 树上子链

    B:树上子链 考察点 : 树的直径 坑点 : long long, 是点权不是边权 一个点也算一条链 析题得侃: 关于树的直径 这道题考察的是树的直径,最好用树形DP来写,具体解释详见上述博客, 这道 ...

  3. JS绑定事件处理函数及处理流程

    一.事件绑定的几种方式: 1.1 ele.on+“事件名“:如div.onclick = function(event){ }; 1.1.1这种方式兼容性非常好,但一个元素的同一个事件上只能绑定一个处 ...

  4. JavaScript-事件处理程序

    DOM事件流: 1.事件冒泡 2.事件捕获 DOM2事件流: 1.事件捕获阶段 2.处于目标阶段 3.事件冒泡阶段 DOM3事件 事件处理程序: 1.HTML事件处理程序: 例一:<input ...

  5. webpack, autoprefixer

    可以通过postcss-loader 添加 const autoprefixer = require('autoprefixer'); ... { loader: 'postcss-loader', ...

  6. spring框架中用到了哪些设计模式

    1.代理模式:在AOP和remoting中被用的比较多 2.单例模式:在spring配置文件中定义的bean默认为单例模式 3.模板方法模式:解决代码重复问题 4.前端控制器模式:spring提供了D ...

  7. ubuntu18.04 编译fortran出现 ‘没有f951这个文件’处理

    机器自带了gcc所以可以编译fortran文件, 使用时, gcc **.for –o ***.out 提示,没有找到f951. 然后去网上找解决方案,有的人说在其他地方找到了f951,然后把他复制到 ...

  8. 2020牛客寒假算法基础集训营5 B.牛牛战队的比赛地 (二分/三分)

    https://ac.nowcoder.com/acm/contest/3006/B 三分做法 #include<bits/stdc++.h> #define inf 0x3f3f3f3f ...

  9. opencv3.2.0+opencv_contrib-3.2.0+vs2015开发配置

    在sift算法实现中,出现了这个问题 出现问题:\vs2015opencv\vs2015\project\mode\mode\sift算法1.cpp(3): fatal error C1083: 无法 ...

  10. Flatmap 和map 区别

    map将函数作用到数据集的每一个元素上,生成一个新的分布式的数据集(RDD)返回 map函数的源码:   def map(self, f, preservesPartitioning=False): ...