一、软件崩溃生成dump的现有主流跨平台方案
- Google Breakpad
google开发的开源、BSD License类型、支持跨平台的崩溃捕获库。
官方网址: 官网介绍 - Google Crashpad
google开发的开源、BSD License类型、支持跨平台的崩溃捕获库。
用于代替Google Breakpad,设计简洁、代码健壮,相比Google Breakpad,主要能支持对Mac OS的进程外崩溃报告。 - qBreakpad
对Google Breakpad的封装,更好适配QT软件,LGPL License类型。
总结: 三种方案均可用于商业软件,而无需开源,方案三对QT软件更适配。
二、基础知识与原理
1、基本概念
dump文件: minidump文件,后缀 *.dmp
,是程序崩溃时的内存转储文件;
pdb文件: 后缀 *.pdb,是程序的符号文件
2、原理
我们在编译的时候,需要在Release版程序中生成调试信息。使用Breakpad提供的dump_syms
工具,从release版本程序导出符号文件。当程序崩溃时,breakpad会捕捉崩溃,并生成dump文件。dump文件可以直接发送到指定服务器,或者由用户手动发给开发者。开发者收到dump文件后,结合符号文件,可通过minidump_stackwalk
工具生成堆栈调用信息文件,这个文件可以直接阅读,定位bug。
3、参考资料
1、中文推荐: Qt Windows系统使用QBreakpad实战
2、官网介绍
三、存在的问题与解决方案
1、Mingw不支持生成pdb文件
证明:
解决方案:
由于mingw平台下不支持生成pdb文件,所以无法用来调试dump文件,但是我们可以通过cv2pdb来转换,将Mingw编译器对软件的调试信息转换为pdb格式。
实现步骤:
1、 qt mingw 生成DUMP文件,和pdb文件
四、当前方案:
暂定使用方案三测试是否可行。
4.1、Windows平台下方案验证
4.1.1、使用VS编译器进行编译
- 编译生成lib静态库
修正QT版本错误,编译handler生成qBreakpad.lib静态库 - Release下崩溃生成dmp文件
a)编译program链接qBreakpad.lib生成test.exe可执行文件
b)在可执行文件中增加点击按钮崩溃的功能
c)点击按钮,出发崩溃钩子,在指定路径生成dmp文件 - 生成pdb文件
增加以下Qmake编译选项,生成test.pdb文件QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO QMAKE_LFLAGS_RELEASE = $$QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO
- pdb与dmp整合定位
a) 使用VS进行调试
导入dmp文件,加载pdb符号文件,点击调试,可以获得崩溃位置如下:
b) 使用windbg调试
有需要再尝试
c) 使用minidump_stackwalk调试
有需要再尝试
4.1.2、使用Mingw编译器进行编译
- 编译生成lib静态库
生成了libqBreakpad.a静态库,不符合windows平台下静态库后缀,但可以使用,需要改为cmake测试能否生成qBreakpad.lib - Release下崩溃生成dmp文件
a)编译program链接libqBreakpad.a生成test.exe可执行文件
b)在可执行文件中增加点击按钮崩溃的功能
c)点击按钮,出发崩溃钩子,在指定路径生成dmp文件 - 生成pdb文件
使用cv2pdb64.exe对test.exe抽取符号表,生成生成test.pdb文件 - pdb与dmp整合定位
a) 使用VS进行调试
导入dmp文件,加载pdb符号文件,点击调试,无法获得崩溃位置,提示如下:
提示不支持改pdb文件,但更具dmp文件基础信息可以区分野指针与空指针。
五、下一步计划
1、测试windbg与minidump_stackwalk是否可以调试cv2pdb64.exe生成的pdb文件
2、分析cv2pdb64.exe生成的pdb文件为什么无法用于调试
3、将Qmake构建脚本转为cmake脚本,尝试编译.lib静态库
欢迎各位C++开发者建言献策!!!