Qt中使用Google Breakpad捕获程序崩溃异常

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
  • minidumpsymbol 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

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是Qt程序崩溃异常捕获的方法: 1.使用qInstallMessageHandler()函数来自定义消息处理程序,以便在程序崩溃时获取相关信息。以下是一个示例代码: ```cpp void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) { QByteArray localMsg = msg.toLocal8Bit(); switch (type) { case QtDebugMsg: fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); break; case QtInfoMsg: fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); break; case QtWarningMsg: fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); break; case QtCriticalMsg: fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); break; case QtFatalMsg: fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); abort(); } } int main(int argc, char *argv[]) { qInstallMessageHandler(myMessageOutput); QApplication a(argc, argv); // ... return a.exec(); } ``` 2.使用Qt的调试器来捕获异常。在Qt Creator,可以通过以下步骤来使用调试器: - 在Qt Creator打开项目并设置断点。 - 单击“调试”按钮以启动调试器。 - 在调试器运行程序并观察变量和堆栈。 - 如果程序崩溃,调试器将停止并显示崩溃信息。 3.使用第三方库来捕获异常,例如Google BreakpadGoogle Breakpad是一个开源库,可用于在Windows、Linux和Mac OS X上捕获程序崩溃信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值