一、崩溃捕捉记录的意义
应用程序发布出去之后用户使用的过程中出现崩溃的情况下,软件需要记录崩溃详情并给用户弹出崩溃提示对话框,提示用户重启软件以及上报(上传)崩溃。
这样做能保证软件在使用过程中发现的bug都能很好的收集起来,并根据崩溃详情修改bug,然后发布修复bug的版本。
如果软件在使用过程中直接闪退没有任何提示,不仅用户体验不好,还无法获取崩溃的原因。之后更具用户反馈的口头描述来找bug就会非常头疼了。
二、在Qt开发中怎样实现崩溃捕捉记录呢?
开发c#应用程序的时候用Log4Net库就可以轻松的获取崩溃后的软件崩溃详情。如果还附带应用程序对应的pdb调试文件Exception报错记录里会有出现崩溃代码的具体行号,非常方便。但是现在开发Qt开发的时候怎样实现呢?
- 如果开发的Qt应用程序只在Windows系统下运行,可以使用“SetUnhandledExceptionFilter”来设置应用程序奔溃捕捉,这样软件在崩溃的时候,这个函数指定的回掉函数就会被调用并返回崩溃详情。返回的崩溃详情为MiniDump格式。这个是windows提供的函数,因此必须包含“#include <Windows.h>”,也就是说这个方法没有办法在其他平台如linux上使用。
- 如果所开发的电脑软件需要在Windows、Mac OS、Linux三个平台上使用呢?
Qt所开发的应用程序本来是跨平台的(一次编码多平台编译),那么Qt自己有没有提供类似的功能呢?答案是没有。但是这个需求确实存在,因此肯定有解决方案,那就是BreakPad。Google breakpad是一个跨平台的崩溃转储和分析框架和工具集合。而且BreakPad本来就是为了解决C、C++异常捕获而开发的。BreakPad支持跨平台,很容易在Qt项目中使用,使跨平台的应用实现跨平台异常捕获。
三、Google breakpad简单介绍
- 官网原文:
Breakpad is a library and tool suite that allows you to distribute an application to users with compiler-provided debugging information removed, record crashes in compact “minidump” files, send them back to your server, and produce C and C++ stack traces from these minidumps. Breakpad can also write minidumps on request for programs that have not crashed.
Breakpad可以捕获发布给用户的应用程序的崩溃,并记录软件崩溃的调试信息到“minidump”文件中。调试信息包括错误行号,报错详情,堆栈错误(stack traces)。软件崩溃时候把生成的“minidump”上传到自己的服务器上就可已方便的获取足够细致崩溃详情。Breakpad提供了简单的上传“minidump”到服务器的代码实现。 - BreakPad 被用于Google Chrome, Firefox, Google Picasa, Camino, Google Earth。
- BreakPad是开源协议下发布的项目由C++开发,目的在于捕捉各个系统平台下的C\C++开发的程序的崩溃详情。从而辅助修改bug。BreakPad支持的系统平台有:windows、linux、mac、ios、solaris、android ndk
四、Google breakpad实现原理简单了解
- 在不同平台下使用平台特有的函数以及方式实现异常捕获:
Windows:通过SetUnhandledExceptionFilter()设置崩溃回掉函数
Max OS:监听 Mach Exception Port 获取崩溃事件
Linux:监听 SIGILL SIGSEGV 等异常信号 获取崩溃事件 - MiniDump文件格式
minidump是由微软开发的崩溃记录文件格式。minidump为二进制文件,体积小。为了保持统一,breakpad在其他系统下也选择生成minidump文件。 - breakpad 查看崩溃详情的方式与原理
breakpad官方的使用架构示意图如下:
示意图要表达的意思如下:
- 包含了breakpad客户端(静态库)的应用程序在发布Release版本的时候。在编译的时候选择保留调试信息。
- 然后使用Breakpad 提供的symbol工具根据release版本程序生成“symbols文件”。“symbols文件”包括程序之前保留的调试信息。
- 发布给用户的release版本程序发生崩溃后包含在程序内“breakpad客户端”会捕捉崩溃并生成“minidump文件”。
- “minidump文件”被应用程序发送到你指定的服务器,或通过其他方式收到用户软件崩溃产生的“minidump文件”。
- 收到“minidump文件”后,结合发布应用的所对应的 “symbols文件”,通过“breakpad minidump processor” 工具来转换生成文本格式的“stack trace 文件”。这个文件内的信息就是程序员可以直接阅读的崩溃堆栈详情。从而准确的找到触发崩溃的bug。
五、在Qt工程中集成Breakpad实现跨平台异常捕获
测试和举例所使用的Qt开发环境在win,macos,都是使用Qt Creater以及Qt creater 的工程文件。
- breakpad一般使用方法:
breakpad提供的是源码,源码提供了configure和Makefile来编译。编译之后获取到一个静态库文件和对应的头文件。在平台的应用软件工程中添加静态库即可使用。在breakpad的源码中有各个平台的使用说明文档,其中Linux平台下的使用方法如下:
#include "client/linux/handler/exception_handler.h"
int main(int argc, char* argv[]) {
google_breakpad::MinidumpDescriptor descriptor("/tmp");
google_breakpad::ExceptionHandler eh(descriptor, NULL, dumpCallback, NULL, true, -1);
crash();
return 0;
}
static bool dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor, void* context, bool succeeded) {
printf("Dump path: %s\n", descriptor.path());
return succeeded;
}
void crash() {
volatile int* a = (int*)(NULL);
*a = 1;
}
- 其中descriptor指定当捕获到崩溃的时候生成minidump文件的储存路径
- 其中dumpCallback这个回掉函数是当保存完minidump文件之后通过这个回掉函数返回minidump文件的保存路径与文件文件名字
- 其中crash()函数是是用于模拟引发应用软件崩溃
- 其中“include "client/linux/handler/exception_handler.h”是特定平台需要包含的头文件
-
Qt多个平台下使用breakpad的方法
当使用qt开发跨平台软件使用breakpad的时候,可以对各个平台下使用breakpad方法做一个封装。从而给qt应用程序提供统一的调用接口。(注意:不同平台调用breakpad的函数和头文件是不同的)由于不同平台下不仅调用函数不同,编译方法也不尽相同。所以这个封装不是特别简单。因此使用使用gitHub上封装好的开源代码了。[buzzySmile/qBreakpad] 这个封装库支持在windows、linux、macos平台下使用breakpad。并且有demo帮助你快速使用qBreakpad。在qt工程中使用qBreakpad的方法如下: