前言
测试的同事反馈程序运行后挂机 1 天后突然闪退,需要找出问题并解决 bug,这里分享一下定位问题的经过。
经过查询资料,打算集成 Google Breakpad 的 Qt 封装库------qBreakpad到程序中,能实现程序奔溃时自动生成dump文件和pdb文件,再经过vs工具分析bug,找到问题。
使用步骤
- 下载源码,编译生成 lib。
- 在程序中 include 头文件,就可以在你的程序中集成了。
- 在程序崩溃时自动生成 dump 文件。
- 利用工具分析 dump 文件。
一、源码准备
1. 下载 Breakpad 源码
https://github.com/google/breakpad
2. 下载 qBreakpad 源码
https://github.com/buzzySmile/qBreakpad.git
3. 下载 LSS 源码
https://github.com/plexinc/breakpad-lss/tree/master
(只需要 linux_syscall_support.h 这个 .h 文件就可以)
或者直接用现成我集成好的:包含了 qBreakpad、Breakpad、LSS 完整的工程。
bash
网盘链接: https://pan.baidu.com/s/1iCmk_wQpU-ZPBn1rGTwQXg
提取码: ea85
如果用网盘的代码下面这一步(第4点)可以忽略。
4.将 qBreakpad、breakpad、lss 源码下载完成后解压后,把 breakpad、lss 放入 qBreakpad 的 third_party 目录下,如下:

二、qBreakpad工程介绍
在qBreakpad源码目录下,使用QtCreator打开qBreakpad.pro工程,如下:

demo工程下,有2个演示程序program和reporter,分别实现了演示生成dump文件、上报dump文件的功能。
handler为静态库工程,该工程封装了Breakpad,直接编译此工程,可生成qBreakpad.lib。
tests为测试工程。
三、编译生成qBreakpad.lib
1.在Debug、Release模式下,编译handler工程,生成2个版本的qBreakpad.lib静态库。由于我只需要在Release模式下调试,下面就只演示Release模式下的编译过程。
编译后生成的 .lib 如下图:

说明:Release模式不会自动生成pdb文件,这里只需要拿到对应的.lib文件即可!
四、在要调试的程序中调用qBreakpad
1.在工程目录下建立qbreakpadlib目录。
2.新建qbreakpadlib\lib\release目录,把release版qBreakpad.lib拷贝至此。
3.再将下图的2个头文件以及singleton文件夹一起拷贝到include下即可。
此时qbreakpadlib的目录结构,如下:

4.在项目的.pro文件中,添加如下内容:
cpp
############ for qBreakpad ############
# qBreakpad中需要使用到network模块
QT += network
# 启用多线程、异常、RTTI、STL支持
CONFIG += thread exceptions rtti stl
# without c++11 & AppKit library compiler can't solve address for symbols
CONFIG += c++11
macx: LIBS += -framework AppKit
# 配置头文件搜索路径和链接库路径
win32:CONFIG(release, debug|release): {
LIBS += -L$$PWD/qbreakpadlib/lib/release/ -lqBreakpad
DEPENDPATH += $$PWD/qbreakpadlib/lib/release
}
else:win32:CONFIG(debug, debug|release): {
LIBS += -L$$PWD/qbreakpadlib/lib/debug/ -lqBreakpad
DEPENDPATH += $$PWD/qbreakpadlib/lib/debug
}
INCLUDEPATH += $$PWD/qbreakpadlib/include
############ for qBreakpad ############
5.然后在main.cpp中添加调用代码,如下:
cpp
#include <QApplication>
#include "QBreakpadHandler.h"//添加头文件
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QBreakpadInstance.setDumpPath("crashes"); // 设置生成dump文件路径
...........
}
五、生成Release pdb文件
之前说过在release模式下,不会生成pdb文件,有这个pdb文件会更容易定位问题
所以,需要在qBreakpadTest.pro文件中,添加如下内容,让release版程序带上调试信息:
cpp
QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
QMAKE_LFLAGS_RELEASE = $$QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO
win系统下,程序的调试信息,是在单独的pdb文件中;在其他linux、mac等系统下,程序的调试信息就包含在程序本体内部,所以带调试信息的程序一般比不带调试信息的大。
清除以后qmake,再次编译,可以看到,已经生成了"程序名.pdb"
六、测试:
故意写了一个会引起程序奔溃的语句

生成dump文件

特别注意
如果使用MinGW编译程序,无法生成pdb文件,这点需要注意一下。必须使用MSVC编译,方可生成pdb文件。
目前我们已经生成了程序的pdb调试信息文件,并且程序执行过程中发生崩溃,也可以自动记录dump文件,这2个文件已经具备,接下来,我们看看如何利用他们定位到bug所在位置。
七、使用VS进行调试
我这里使用VS 2017,来进行如下的操作。
1.打开dump文件
Vs文件菜单下,选择"打开"->"文件",或者直接拖拽。
2.找到dump文件,并打开。
3.设置pdb文件路径
接下来,点击"设置符号路径",点击"+"号,添加pdb文件路径,之后,"确定"。如下:


选择:使用仅限本机进行调试

看到它自己定位到出现bug的位置了。

注意:生成bug时候的代码必须和分析bug时候的代码一样,不然工具就会找不到出现bug的位置