Qt中使用Google Breakpad捕获程序崩溃异常
Linux下如何捕获程序崩溃异常的方法
Google Breakpad源码的下载和编译
- 下载
breakpad
git clone https://github.com/google/breakpad.git
-
下载
linux_syscall_support.h
从
https://chromium.googlesource.com/linux-syscall-support/
下载该文件,并放到breakpad/src/third_party/lss/
中 -
编译
cd breakpad
./configure --prefix=/usr/breakpad
make
sudo make install
添加环境变量
- 修改
.bashrc
文件
vim ~/.bashrc
在.bashrc
文件的末尾添加刚刚生成的文件的路径
export PATH=$PATH:/usr/breakpad/bin
export LIBRARY_PATH=$LIBRARY_PATH:/usr/breakpad/lib
- 更新环境变量
source ~/.bashrc
如何使用
#include <QCoreApplication>
#include <QDir>
#include <QDebug>
#include "client/linux/handler/exception_handler.h"
// 程序崩溃回调函数;
static bool dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor,
void* context, bool succeeded)
{
if (succeeded)
{
qDebug() << descriptor.path() << " Create dump file success";
}
else
{
qDebug() << descriptor.path() << " Create dump file failed";
}
return succeeded;
}
// 触发crash来测试
void crash() {
volatile int* a = (int*)(NULL);
*a = 1;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
//获取程序当前运行目录
QString appDirPath = QCoreApplication::applicationDirPath() + "/crash";
QDir dir;
if (!dir.exists(appDirPath))
{
bool res = dir.mkpath(appDirPath);
qDebug() << "New mkdir " << appDirPath << " " << res;
}
// minidump文件写入到的目录
google_breakpad::MinidumpDescriptor descriptor(QString(appDirPath).toStdString());
// 创建捕捉程序异常对象;
google_breakpad::ExceptionHandler eh(descriptor,
nullptr,
dumpCallback,
nullptr,
true,
-1);
crash();
return a.exec();
}
这样就会在crash
路径下生成*.dmp
文件
附录
ExceptionHandler(const MinidumpDescriptor& descriptor,
FilterCallback filter,
MinidumpCallback callback,
void* callback_context,
bool install_handler,
const int server_fd);
- descripter,minidump文件写入的目录
- filter,可选,在写minidump文件之前,会先调用filter回调。根据它返回true/false来决定是否需要写minidump文件。
- callback, 可选,在写minidump文件之后调用的回调函数
- callback_context,
- install_handler, 如果为ture,不管怎样当未捕捉异常被抛出时都会写入minidump文件,如果为false则必须明确调用了 WriteMinidump 才会写入minidump 文件
- server_fd, 如果为-1,则使用同线程模式(in-precess),如果有一个有效的值,则使用跨线程模式(out-of-process)
注意
需要注意的是,你必须在callback回调函数中做尽量少的工作,因为你的程序处于一个不安全的状态,它需要无法安全的去分配内存,或调用其他共享库中的函数。安全的方式是 fork 和 exec 一个新进程去做想要做的事情。如果你需要在回调中做一些工作,breakpad源码提供一些简单的重新实现的libc库里的方法,来避免直接调用libc, 并提供一个a header file for making linux system calls,来避免直接调用其他共享库的方法。
查看 .dmp
文件
- 生成symbol files
为了生成可读的stack trace, breakpad需要你将binaries里的调试符号(debugging symbols)转换成基于文本格式的symbol files。
dump_syms ./breadpadtest > breadpadtest.sym
- 将
minidump
、symbol files
生成可读的stack trace文件(可读的堆栈跟踪文件)
breakpad包含一个叫做 minidump_stackwalk 的工具来将 minidump 文件生成一个人可读的stack trace(有说用外加symbol files来生成,没区别)
minidump_stackwalk *.dmp > test.txt
依据crashed
地址,可定位在程序中crash
的位置
测试例子、breakpad源码:
https://download.csdn.net/download/u011720560/12344059
参考
https://github.com/google/breakpad/blob/master/docs/linux_starter_guide.md
https://www.jianshu.com/p/295ebf42b05b
https://www.cnblogs.com/MakeView660/p/6077436.html