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

我们不能再客户电脑上安装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. Verilog-case、casez和casex的区别

    参考博客:https://www.cnblogs.com/guolongnv/articles/6906929.html 1.基本概念 1)?表示z,而不是“dont care” 2)区分: case ...

  2. sqli-labs less-15 --> less-16

    Less-15(布尔/时间盲注) 1.判断是否存在注入点 无论是输入admin/admin’/admin” 都显示回显正常,于是执行uname=admin' and sleep(5)#&pas ...

  3. Android开发 文件读写openFileOutput与openFileInput

    package com.example.androidtest; import java.io.ByteArrayOutputStream; import java.io.FileInputStrea ...

  4. Net项目添加 WebAPI

    1.新建一个  WebApiConfig.cs public static void Register(HttpConfiguration config) { // Web API 配置和服务 // ...

  5. Ajax基础原理与应用

    Ajax函数封装ajax.js // Get / Post // 参数 get post // 是否异步 // 如何处理响应数据 // URL // var handleResponse = func ...

  6. Vuejs中created和mounted的区别

    created:在模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图. mounted:在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作

  7. 洛谷P3381 MCMF【网络流】

    题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 输入格式 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向 ...

  8. eclipse中创建了web项目,src下创建子目录是平级的情况

    1.在以下可设置不同的视图 windows->show view菜单 ->点Other......    然后在搜索框里输入你想要的视图 2.在Project Explorer下创建的包看 ...

  9. Struts2学习-jsp中超链接传参问题

    今天在学习过程中对struts2中超链接的传参问题产生了一些疑惑,不明白jsp中的超链接如何将参数传到Action方法中去的. <s:iterator value="categorys ...

  10. Spring Boot整合Freemarker

    一.首先导入依赖 <!-- 添加freemarker模版的依赖 --> <dependency>     <groupId>org.springframework. ...