Qt程序crash信息的捕捉与跟踪(qt-mingw)

2024-06-08 01:58

本文主要是介绍Qt程序crash信息的捕捉与跟踪(qt-mingw),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在用qt编写程序时经常会遇到崩溃问题,如果抓取不到crash堆栈信息就会对崩溃问题束手无策,只能对其进行复现,推断。

 

目录

一般解决crash问题时有如下步骤:

如何执行以上3步骤,下面我详细介绍如何操作;

步骤1:

步骤2:

步骤3:

网友评论:

 

 


一般解决crash问题时有如下步骤:

 

  1. 从软件发行版本能跟获得debug信息,在不同平台下有不同的表现方式,目前只讨论qt-mingw方式,这种方式可以利用修改工程文件配置项编译时讲debug信息加入应用程序当中;当然这会增加发行版应用程序的体积。如果想体积变小可以strip应用程序。
  2. 获得crash堆栈信息
  3. 根据crash堆栈信息和1中的debug信息来查找软件崩溃的位置。


如何执行以上3步骤,下面我详细介绍如何操作;

步骤1:

在工程文件.pro中加入如下代码,生成可执行文件中就会带debug信息:
QMAKE_CXXFLAGS_RELEASE += -g

QMAKE_CFLAGS_RELEASE += -g

QMAKE_LFLAGS_RELEASE = -mthreads -Wl

前两行意识意思为在release版本中增加debug信息;第三行意思为release版本中去掉-s参数,这样就生成对应符号表,可以调试跟踪;

 

步骤2:


(注:目前只讨论windows平台,linux和mac暂不讨论;)

需要调用window平台系统api进行截取crash信息及获得crash堆栈。
首先在main函数中调用系统API SetUnhandledExceptionFilter,该函数有个设置回调函数,软件崩溃时会回调该系统函数,并传回崩溃地址信息等。

如何调用,请看如下代码:

long __stdcall   callback(_EXCEPTION_POINTERS*   excp)
{CCrashStack crashStack(excp);QString sCrashInfo = crashStack.GetExceptionInfo();QString sFileName = "testcrash.log";QFile file(sFileName);if (file.open(QIODevice::WriteOnly|QIODevice::Truncate)){file.write(sCrashInfo.toUtf8());file.close();}qDebug()<<"Error:\n"<<sCrashInfo;//MessageBox(0,L"Error",L"error",MB_OK);QMessageBox msgBox;msgBox.setText(QString::fromUtf8("亲,我死了,重新启动下吧!"));msgBox.exec();return   EXCEPTION_EXECUTE_HANDLER;
}int main(int argc, char *argv[])
{SetUnhandledExceptionFilter(callback);QApplication a(argc, argv);Dialog w;w.show();return a.exec();
}

 

注:CCrashStack 是我写的类,目的是调用系统API获取crash堆栈信息;(目前只针对windows平台)

 

步骤3:

通过qt命令行进入 执行命令:
objdump -S xxx.exe >aaa.asm

 

命令执行完成后,根据步骤2中获得的crash堆栈信息在aaa.asm中查找响应地址,即可得到崩溃具体位置。


附件为测试demo,里面有完整代码,各位可下载体验。

Demo下载地址:

http://download.csdn.net/detail/lanhy999/6341987

 

网友评论:

  • SHIXINGYA: EXE太大,asm生成不全,怎么解决? asm生成到465350行就不写了(8个月前#7楼)收起回复

  • SHIXINGYA回复 SHIXINGYA: http://www.qtcn.org/bbs/read-htm-tid-65581.html(8个月前)

  • 振星: 您好,我直接编译您的代码,在release下编译遇到该问题: g++: error: unrecognized command line option '-Wl' 我的环境是Qt 4.8.6,使用mingw编译的。请问我是否还有什么没有地方没有设置正确呢?(3年前#6楼)收起回复

  • 叹逍遥回复 振星: http://stackoverflow.com/questions/22282871/unrecognized-command-line-option-wi http://stackoverflow.com/questions/21305309/g-doesnt-recognize-the-option-wl 我也碰到了,将那三行加入工程后release编译报错,根据第二篇讨论的答案,我去掉-Wl之后编译OK,后面又实验了下-Wl后面加逗号也可以并且两种编译出的exe md5一样,不知道实际编译-Wl参数到底有没有进去,不过感觉后面加逗号应该妥当一点 QMAKE_LFLAGS_RELEASE = -mthreads -Wl, 或者 QMAKE_LFLAGS_RELEASE = -mthreads(1年前)
  • fanweimianA: 命令执行完成后,根据步骤2中获得的crash堆栈信息在aaa.asm中查找响应地址,即可得到崩溃具体位置 能否做个说明,是怎么找到具体位置的,log文件,asm文件我都有了,不知道怎么看,谢谢(4年前#5楼)收起回复举报回复

  • 叹逍遥回复 叹逍遥: 上面两段分别是记录的crash日志和dump出的asm, Exception Addr: 00401E20 说明代码地址00401E20出发生异常,Write Address: 00000000说明异常的时候正在访问0x00000000内存地址,对比asm中00401E20处,正好是博主构造的对空指针进行写入的异常处。剩下的Registers和Call Stack保存了现场的寄存器和堆栈信息。 不过有个问题是这东西release版本带着调试信息发布,很容易被人看出源码,不过自己写的小程序无所谓了 末尾感谢博主的分享!(1年前)
    • 叹逍遥回复 fanweimianA: 虽然时间挺久了,但是自己折腾了好长时间忍不住回复一下: Exception Addr: 00401E20 Module: D:\QT\build-TestCrash-Desktop_Qt_5_8_0_MinGW_32bit-Release\release\TestCrash.exe Exception Code: C0000005 Write Address: 00000000 Instruction: C7 05 00 00 00 00 00 00 00 00 0F 0B 90 90 90 90 Registers: EAX: 00000000 EBX: 00000000 ECX: 0077FE04 EDX: 00000000 ESI: 0077D428 EDI: 0077FE04 ESP: 0077D31C EBP: 0077D408 EIP: 00401E20 EFlags: 00010246 Call Stack: 00401E20 D:\QT\build-TestCrash-Desktop_Qt_5_8_0_MinGW_32bit-Release\release\TestCrash.exe 620C2D1F C:\Qt\5.8\mingw53_32\bin\Qt5Widgets.dll void Dialog::on_btnTestCrash_clicked() { int *p = NULL; *p = 4; 401e20: c7 05 00 00 00 00 00 movl $0x0,0x0 401e27: 00 00 00 401e2a: 0f 0b ud2 401e2c: 90 nop 401e2d: 90 nop 401e2e: 90 nop 401e2f: 90 nop 00401e30 &lt;__ZL7sprintfPcPKcz&gt;: }(1年前)

  • sunlj181: 你好。这个信息时怎么对应的?(4年前#4楼)

  • aiolia0122: 命令执行完成后,根据步骤2中获得的crash堆栈信息在aaa.asm中查找响应地址,即可得到崩溃具体位置 能否做个说明,是怎么找到具体位置的,log文件,asm文件我都有了,不知道怎么看,谢谢(4年前#3楼)

  • 资深码农: 1.mingw 2.mingw下生成的符号和应用程序文件是一起的;通过objdump命令可以产生出符号文件;例如: objdump -s a.exe &gt;a.asm(4年前#2楼)

  • yanan_gd: 你好,问两个问题 1.你给的这个demo的编译环境是什么,mingw还是msvs? 2.步骤1中的生成的符号文件在哪里? 谢谢(4年前#1楼)收起回复

    • 资深码农回复 yanan_gd: 1.mingw 2.mingw下生成的符号和应用程序文件是一起的;通过objdump命令可以产生出符号文件;例如: objdump -s a.exe &gt;a.asm(4年前)

 

--------------------- 
作者:资深码农 
来源:CSDN 
原文:https://blog.csdn.net/lanhy999/article/details/12189375 
版权声明:本文为博主原创文章,转载请附上博文链接!

 

 

 

 

这篇关于Qt程序crash信息的捕捉与跟踪(qt-mingw)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1040921

相关文章

uniapp接入微信小程序原生代码配置方案(优化版)

uniapp项目需要把微信小程序原生语法的功能代码嵌套过来,无需把原生代码转换为uniapp,可以配置拷贝的方式集成过来 1、拷贝代码包到src目录 2、vue.config.js中配置原生代码包直接拷贝到编译目录中 3、pages.json中配置分包目录,原生入口组件的路径 4、manifest.json中配置分包,使用原生组件 5、需要把原生代码包里的页面修改成组件的方

Java面试八股之怎么通过Java程序判断JVM是32位还是64位

怎么通过Java程序判断JVM是32位还是64位 可以通过Java程序内部检查系统属性来判断当前运行的JVM是32位还是64位。以下是一个简单的方法: public class JvmBitCheck {public static void main(String[] args) {String arch = System.getProperty("os.arch");String dataM

【操作系统】信号Signal超详解|捕捉函数

🔥博客主页: 我要成为C++领域大神🎥系列专栏:【C++核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞👍收藏⭐评论✍️ 本博客致力于知识分享,与更多的人进行学习交流 ​ 如何触发信号 信号是Linux下的经典技术,一般操作系统利用信号杀死违规进程,典型进程干预手段,信号除了杀死进程外也可以挂起进程 kill -l 查看系统支持的信号

通过高德api查询所有店铺地址信息

通过高德api查询所有店铺地址电话信息 需求:通过高德api查询所有店铺地址信息需求分析具体实现1、申请高德appkey2、下载types city 字典值3、具体代码调用 需求:通过高德api查询所有店铺地址信息 需求分析 查询现有高德api发现现有接口关键字搜索API服务地址: https://developer.amap.com/api/webservice/gui

一道经典Python程序样例带你飞速掌握Python的字典和列表

Python中的列表(list)和字典(dict)是两种常用的数据结构,它们在数据组织和存储方面有很大的不同。 列表(List) 列表是Python中的一种有序集合,可以随时添加和删除其中的元素。列表中的元素可以是任何数据类型,包括数字、字符串、其他列表等。列表使用方括号[]表示,元素之间用逗号,分隔。 定义和使用 # 定义一个列表 fruits = ['apple', 'banana

美容美发店营销版微信小程序源码

打造线上生意新篇章 一、引言:微信小程序,开启美容美发行业新纪元 在数字化时代,微信小程序以其便捷、高效的特点,成为了美容美发行业营销的新宠。本文将带您深入了解美容美发营销微信小程序,探讨其独特优势及如何助力商家实现业务增长。 二、微信小程序:美容美发行业的得力助手 拓宽客源渠道:微信小程序基于微信社交平台,轻松实现线上线下融合,帮助商家快速吸引潜在客户,拓宽客源渠道。 提升用户体验:

QT 中ListView和ListWidget有什么区别

ListView和ListWidget在Qt框架中都是用于显示列表数据的控件,但它们在使用方法和特性上存在一些明显的差异。以下是关于它们用法不一样的地方的详细分析: 数据管理方式: ListView:使用QAbstractItemModel数据模型来管理和显示列表数据。QAbstractItemModel是一个抽象类,允许开发者自定义数据模型以适应特定的数据结构和需求。这使得ListView在处

程序人生--拔丝地瓜

一个会享受生活的人,难免会执迷于探索“三餐茶饭,四季衣裳”的朴素涵义。如今在这繁杂喧闹、竞争激烈的社会环境里,如何才能从周而复始的生活中挖掘出一点儿期待!这是一个仁者见仁智者见智的开放性话题。对于大部分的人来说,看电影、运动、旅游、美食、加班....是假日的备选安排。 春节临走之前,再次尝试“拔丝地瓜”,为何要强调“再次”二字?因为这道甜菜我已经尝试过很多次,失败与成功都经历过。十几年的烧饭经历

通知中心设置一个键盘的捕捉事件

//通知中心监听键盘的frame发生改变