58点击软件奔奔_你开发的软件不知道哪里跑飞闪退了?这个办法可以帮忙定位...

40eaea5ddf956b24e2c410ec84f44a41.png

很多时候你开发的软件奔溃了,来不及观察现象就跑飞闪退了,如何定位到有问题的代码是一个难题。

c502450a5805f055051dd3bd6e758364.png

无法定位自己代码里错误的位置,这件事情本身很容易让程序员奔溃。地基里有一颗不知何时爆炸、无迹可寻的炸弹,在这基础上楼房盖的再高也是危房,是不能住人的。而程序员如果在自己的代码了埋了一个不知何时奔溃、无迹可寻的种子,那么他肯定会怀疑这个作品的意义,即使是整年的心血,也会有将它完整删除的冲动。

a1be397f520b70d7d7650308a88a0164.png

最近,在我开发的Qt桌面程序里,就遇到了一个很难定位的bug。具体表现为当我点击退出时,程序在相当长的一段时间里处于无响应状态,然后提醒程序异常结束。以往遇到程序异常结束,我会熟练地打开qtcreator的调试器,如果程序有异常抛出时,调试器会自动帮你定位到出错的代码。

4ba50a3135814d261355ba4b930891c1.png

然而这一次,我的软件有大量动态创建的对象,软件退出前会先销毁它们,而当打开调试器的时候,对象的销毁非常缓慢,需要30分钟的样子才能到达软件奔溃的位置,而且也不能保证奔溃每次都会出现,效率相当底下。[但我等(mei)得(ban)起(fa),所以我还是静静地等待了]

而更加让人无奈的是,当我把调试器好不容易定位到的错误代码修复、确定调试器下不会再奔溃后,关闭调试器再打开,软件退出时异常依然存在。

7731bfc420cba3dc66e1f7818e45ba6f.png

不用调试器观察bug就存在,观察了bug就不存在,我好像发现了不起的东西。。。

39382ed98fb5280c4610b01be70630fc.png
bug二象性

要打破这无奈的局面,我需要找到一个可以不借助调试器就可以观察异常堆栈的方法。印象里软件奔溃退出,唯一能记录程序执行状态的,应该就是核心转储dump了,就从这里入手。很快,我就找到了Qt捕获软件异常,并且生成转储文件的解决方案。

https://blog.csdn.net/taoerit/article/details/76297484​blog.csdn.net

有了转储文件,接下来就是寻找分析它的方法。在搜索引擎上一通操作下来,定位到了windbg神器。我安装的是windbg的全新版本,windbg preview(下载地址:https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugger-download-tools)。安装完直接双击便可以打开dump文件,输入!analyze -v,就可以自动分析出异常退出时候程序的运行堆栈情况。

3475eed864b4735e38c5ddea8de0c4b3.png
!analyze -v 运行结果

从分析结果的第4行可以看出,程序的异常发生在QSGnode的destroy()函数调用以后,而我的程序里确实有几个类继承了QSGNode,如果我从它们的析构函数入手,或许就能定位错误的代码了。但仅仅从这些堆栈信息来定位错误位置依然是很艰辛,有没有可以直接告诉我出错的代码在哪一行的方法呢?

d1daa834b6deb09a90c6b10a3ba75037.png

网上的帖子告诉我,结合PDB(Program DataBase)符号文件,windbg才能发挥出最大的魔力。然而非常不幸的是,我正在使用的MingW版本Qt无法生成pdb文件,我开始明白大家在说的MingW版本调试器很鸡肋,是怎么一回事了。[更新:一天visual studio的调试器体验下来,不管是加载速度,还是bug位置的定位、变量查看、运行时内存CPU占用情况,是全方位的香。qtcreator的debuger是什么垃。。。]

花了点时间重新安装VS2017版本的Qt,并且将工程迁移到VS2017版本,解决了一些兼容性问题,并根据下面链接的操作,确保软件可以正常生成PDB文件。

https://blog.csdn.net/qq_26374395/article/details/90313546​blog.csdn.net

到这一步的时候已经凌晨了,睡觉这件事情索然无味,让我愉快地再奔溃一次,生成如下的DUMP和PDB文件。

28171a395e2e4538b86f141e116415a2.png
pdb在qt工程的build目录,dmp的目录在代码中更改

接下来在打开的windbg preview里,点击文件→settings→debugging settings,将Symbol path设设置成pdb文件所在的目录,点击OK。

8aadd4f9cf74cfce101c3eea9d1e47bd.png
Symbl Path写入DB文件所在目录,其他的还不会用,默认吧

一切准备就绪,回到windbg preview主页面,在command窗口输入!analyze -v,得到了以下的运行结果。

0fb906d5530e0e0c820fe330c07a5e55.png
windbg 直接指出了奔溃那一行代码

看到这里,哪里出错了,一目了然。。。简单分析得知,原来,软件退出的时候,Qt核心把rbw_ptr_自动delete了,并且没有设置成nullptr,导致LineNode访问到野指针了呀。

简单修改修改,软件正常退出的那一刻,睡意终于来袭了~~~

ff5c28e0747b0049db92d6881505ec1d.png

e96b702dd51455d628da47c4960e5dde.png

上面讲述了我使用Qt进行软件奔溃位置定位的方法,即使不是在Qt这个框架下开发,相信也有生成DUMP和PDB文件的方法的。发现了windbg之后,笔者发现自己对调试的技术还是很无知的,马不停蹄地买了本书,研究一下在软件调试方面还有什么我不知道的黑科技。

前段时间围观了写工业级别代码是怎样一种体验这个问题:写工业级别代码是怎样一种体验?

工业软件听起来遥不可及,其实一句永远不能奔溃就是他们最基础的要求了。所以一个写工业级别软件的人,手里的调试黑科技肯定不少吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值