热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Qt生成dump文件及windbg调试(进阶版)

一、异常捕获和dump文件生成还是简单的说一下吧,各位不了解的也可以看看本人的另一篇博客。也可以直接参考如下:main.cpp1#includemainwindow.h2#incl

一、异常捕获和dump文件生成

还是简单的说一下吧,各位不了解的也可以看看本人的另一篇博客。也可以直接参考如下:
main.cpp

1 #include "mainwindow.h"
2 #include
3 #include
4 #include "Login/logindlg.h"
5 #include
6 #include
7 #include
8 #pragma comment(lib, "user32.lib")
9 #pragma comment(lib, "dbghelp.lib")
10
11
12 void GetExceptionDescription(DWORD errCode,QString& err)
13 {
14 #if 0
15
16
17 #else
18 // errCode = 0xc0000005;
19 LPTSTR lpMsgBuf = NULL;
20 HMODULE Hand = LoadLibrary(TEXT("ntdll.dll"));
21 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
22 FORMAT_MESSAGE_IGNORE_INSERTS/*FORMAT_MESSAGE_FROM_SYSTEM*/|
23 FORMAT_MESSAGE_FROM_HMODULE,
24 Hand,
25 errCode,
26 MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
27 (LPTSTR)&lpMsgBuf,
28 0,NULL);
29 err = QString::fromWCharArray( lpMsgBuf );
30 qDebug()<<err;
31 LocalFree(lpMsgBuf);
32 #endif
33 }
34
35
36 LONG ApplicationCrashHandler(EXCEPTION_POINTERS *pException){//程式异常捕获
37 /*
38 ***保存数据代码***
39 */
40 //创建 Dump 文件
41 qDebug()<<"触发异常!";
42 QString createPath = QCoreApplication::applicationDirPath()+"/Dumps";
43 QDir dir;
44 dir.mkpath(createPath);
45 createPath=QString("%1/dump_%2.dmp").arg(createPath).arg(QDateTime::currentDateTime().toString("yyyy_MM_dd_hh_mm_ss_zzz"));
46 std::wstring wlpstr = createPath.toStdWString();
47 LPCWSTR lpcwStr = wlpstr.c_str();
48
49 HANDLE hDumpFile = CreateFile(lpcwStr,
50 GENERIC_WRITE,
51 0,
52 NULL,
53 CREATE_ALWAYS,
54 FILE_ATTRIBUTE_NORMAL,
55 NULL);
56 if( hDumpFile != INVALID_HANDLE_VALUE){
57 //Dump信息
58 MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
59 dumpInfo.ExceptiOnPointers= pException;
60 dumpInfo.ThreadId = GetCurrentThreadId();
61 dumpInfo.ClientPointers = FALSE;
62 //写入Dump文件内容
63 MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpNormal, &dumpInfo, NULL, NULL);
64 }
65 //这里弹出一个错误对话框并退出程序
66 EXCEPTION_RECORD* record = pException->ExceptionRecord;
67 QString errCode(QString::number(record->ExceptionCode,16)),errAdr(QString::number((UINT)((UINT_PTR)record->ExceptionAddress),16));;
68 QString errstr;
69 GetExceptionDescription(record->ExceptionCode,errstr);
70 if(record->NumberParameters>0){
71 if(record->ExceptionInformation[0]==0){
72 errstr+="\r\n访问冲突,线程试图读取不可访问的数据";
73 }else if(record->ExceptionInformation[0]==1){
74 errstr+="\r\n访问冲突,线程尝试写入不可访问的地址";
75 }
76 }
77 QMessageBox::critical(NULL,"程式崩溃","

程式崩溃
"+
78 QString("
错误代码:%1
错误地址:%2
具体原因:%3
").arg(errCode).arg(errAdr).arg(errstr),
79 QMessageBox::Ok);
80 return EXCEPTION_EXECUTE_HANDLER;
81 }
82
83 int main(int argc, char *argv[])
84 {
85 QApplication a(argc, argv);
86 SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)ApplicationCrashHandler);//注冊异常捕获函数
87 //唯一性检测
88 QSharedMemory singleton(a.applicationName());
89 if(!singleton.create(1)) { //已经存在的
90 QMessageBox::critical(nullptr, QObject::tr("错误"),
91 QObject::tr("程序已经在运行,请先关闭!"));
92 return -1;
93 }
94 LoginDlg pLdlg;
95 MainWindow w;
96 QObject::connect(&pLdlg,&LoginDlg::sig_sendCurrentLoginUser,&w,&MainWindow::slot_setCurrentLoginUser);
97 if(pLdlg.exec()==QDialog::Accepted){
98 w.show();
99 #if 0
100 return a.exec();
101 #else
102 int ret = a.exec();
103 if (ret == 773) {
104 singleton.detach();
105 QProcess::startDetached(qApp->applicationFilePath(), QStringList());
106 return 0;
107 }
108 return ret;
109 #endif
110 }else{
111 return -1;
112 }
113 }

根据异常代码获取错误描述的函数,自定义的。

1 void GetExceptionDescription(DWORD errCode,QString& err)

异常捕获回调函数,windows系统固定参数的,关于EXCEPTION_POINTERS 异常结果,可以查看MSDN官方文档,有详细的介绍。

1 LONG ApplicationCrashHandler(EXCEPTION_POINTERS *pException)

里面用到了唯一性检测(只能打开一个exe程序),以及自动重启的相关代码,需要的可以参考(白嫖…)


二、调试

1.安装Windbg Preview

目前已知该软件唯一安装途径好像只有微软商店,反正博主是从微软商店下载的


2.调试

先手动制造一个异常吧,就0x0000005常见的吧,内存访问冲突,或者你弄一个除0的也可以,然后会在程序当前目录的Dump文件夹下生成一个异常的mini dump文件,如下图:

 异常文件:

 打开刚才安装的windbg preview,设置一下符号缓存文件路径,以及你自己程序的pdb文件路径,友情提示,Qt在release模式下生成pdb文件需要在pro文件增加如下配置:

1 QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
2 QMAKE_LFLAGS_RELEASE += $$QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO

好了,继续我们的调试,配置如下

 配置完成之后,将刚才生成的pdb文件拖入command窗口,然后点击自动分析:

 此时会处于BUSY状态,从微软服务器下载各种符号文件,等他完成。

 之后,可以看到调用堆栈信息,以及错误代码。094(除0错误),因为之前赋值为0了,==改成=了。

1 if(mGridLines=0) mGridLines=1;
2 if(mGridColumns=0) mGridColumns=1;

所以后续调用就出现除0的问题,可以直接看到红色框内,源码第61行有问题,感觉比windows自带的windbg强大太多了。

另外还有个问题,就是通过FormatMessage获取错误码对应的描述的时候,访问冲突会出现如下描述:“0x%p 指令引用了 0x%p 内存。该内存不能为 %s。\r\n”,占位符的参数是否需要通过FormatMessage的最后一个参数va_list传递进去,或者说有其他的方案,能完整显示出具体指令和内存地址,目前还没有解决,虚心请教各位大佬,不胜感激。

总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了windbg preview的使用以及异常捕获dump文件的调试。博主也是在成长中的菜鸟,文字如有错误,欢迎指正,大家共同探讨。



推荐阅读
  • vue使用
    关键词: ... [详细]
  • 本文介绍了C++中省略号类型和参数个数不确定函数参数的使用方法,并提供了一个范例。通过宏定义的方式,可以方便地处理不定参数的情况。文章中给出了具体的代码实现,并对代码进行了解释和说明。这对于需要处理不定参数的情况的程序员来说,是一个很有用的参考资料。 ... [详细]
  • 本文介绍了一个程序,可以输出1000内能被3整除且个位数为6的所有整数。程序使用了循环和条件判断语句来筛选符合条件的整数,并将其输出。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
  • 使用eclipse创建一个Java项目的步骤
    本文介绍了使用eclipse创建一个Java项目的步骤,包括启动eclipse、选择New Project命令、在对话框中输入项目名称等。同时还介绍了Java Settings对话框中的一些选项,以及如何修改Java程序的输出目录。 ... [详细]
  • c语言\n不换行,c语言printf不换行
    本文目录一览:1、C语言不换行输入2、c语言的 ... [详细]
  • 本文介绍了一种划分和计数油田地块的方法。根据给定的条件,通过遍历和DFS算法,将符合条件的地块标记为不符合条件的地块,并进行计数。同时,还介绍了如何判断点是否在给定范围内的方法。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ... [详细]
  • 解决文件名过长下载失败问题的jQuery方案
    本文介绍了使用jQuery解决文件名过长导致下载失败的问题。原方案中存在文件名部分丢失的问题,通过动态生成隐藏域表单并提交的方式来解决。详细的解决方案和代码示例在文章中给出。 ... [详细]
  • 单页面应用 VS 多页面应用的区别和适用场景
    本文主要介绍了单页面应用(SPA)和多页面应用(MPA)的区别和适用场景。单页面应用只有一个主页面,所有内容都包含在主页面中,页面切换快但需要做相关的调优;多页面应用有多个独立的页面,每个页面都要加载相关资源,页面切换慢但适用于对SEO要求较高的应用。文章还提到了两者在资源加载、过渡动画、路由模式和数据传递方面的差异。 ... [详细]
author-avatar
恩和佳蓉伟诚
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有