zoukankan      html  css  js  c++  java
  • mac下利用Breakpad的dump文件进行调试

    一、前情回顾

    最近把公司的一个视频处理程序更新了一个版本,准备提交测试的发现了崩溃的情况。这个程序采用Qt和ffmpeg技术栈开发,主要用于对视频进行渲染拼接处理,在Windows和mac两个平台同时进行发布。在windows上测试完一切正常,然而就在我以为一切大功告成的时候,测试的同事直接给我来了个当头棒喝,程序崩溃了!没有道理啊,同一套代码在Windows上安然无恙,在Mac上为何直接崩溃?好消息是程序在崩溃的时候保存了dump文件。

    这得感谢前段时间集成的Google Breakpad了。Google Breakpad是Google开发的一个跨平台异常捕获和dump文件(准确的说是mini dump)生成的开发库。利用这个库可以在Windows, Mac, Linux, iOS, Android平台上对程序异常崩溃进行捕获,并生成dump文件供后期调试。据说Google Chrome, Chromium, Firefox都使用了这套机制,因此其可用性是经得起考验的,并且这个库现在依然更新的很频繁。

     如此强大的东西,怎么使用呢?好在网上关于breakpad的资料是还是挺多的,只不过都不是很完整很简洁。要么就只介绍了实现原理、或者只介绍了怎么编译、或者就只介绍了怎么集成,对于新手使用非常不友善。这里就根据我在Windows和Mac两个平台的使用经验来总结下吧。

    二、breakpad的使用

     breakpad以源代码的形式发布,所以首先要从仓库中把代码下下来:

    git clone https://chromium.googlesource.com/breakpad/breakpad  

    这个是Google的代码仓库,基于国内的环境需要把VPN打开。下载下来的代码包含了windows, mac, linux三个平台所有的文件了,也包含了各个平台的工具源码。没错,breakpad的工具需要自己编译。

    假设源代码下载到了E:/breakpad,那么进入到这个目录运行make命令:

    ./configure
    make

    在Windows上需要用gyp工具来编译,所以还得下载gyp非常麻烦。在mac上就非常简单了,直接运行上述命令即可生成静态库文件。但是工具的话需要进入到tools目录,里面有个已经配置好的xcode工程,直接打开即可编译。

    不过要注意的是,最新的breakpad源码在编译工具的时候会报错:

    Undefined symbols for architecture x86_64:
      "google_breakpad::BaseName(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
          google_breakpad::DumpSymbols::CreateEmptyModule(google_breakpad::scoped_ptr<google_breakpad::Module>&) in dump_syms.o
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)

    解决办法是:

     

     在这一步中我们编译源码主要是为了得到两个工具:minidump_stackwalkdump_syms。这两个分别有什么用呢?dump_syms用于从可执行程序中抽取出调试符号保存到syms符号文件中,而minidump_stackwalk则根据syms文件来分析mini dump文件,得到一个可读性强的崩溃调用堆栈。由于我的工程是基于Qt的,所以我直接利用了Github上面的一个开源项目进行编译。这个项目针对Qt剔除了一些无用的头文件,并对源代码做了稍微的调整。

    基于QMake的工程,可以直接用Qt Creator打开编译。在Windows上和Mac上无缝支持。编译即可得到我们需要的lib文件了。这个在我们后面集成工程中链接需要用到。当然也可以直接将源代码集成到工程去。

    接下来就讲讲如何集成吧。集成步骤其实非常简单,直接上代码:

    #ifdef _WINDOWS
    #include <client/windows/handler/exception_handler.h>
    #else
    #include <client/mac/handler/exception_handler.h>
    #endif
    
    #ifdef _WINDOWS
    bool minidumpCB(const wchar_t *dump_path, const wchar_t *id, void *context, EXCEPTION_POINTERS *exinfo, MDRawAssertionInfo *assertion, bool succeeded) {
    #else
    bool minidumpCB(const char* dump_path, const char* id, void* context, bool succeeded) {
    #endif
        if (succeeded) {
            std::wcout << "Mini Dump file: " << id << ".dump Path: " << dump_path << std::endl;
        }  
        return succeeded;
    }
    
    int main() {
    #ifdef NDEBUG // 只在Release模式下启用Breakpad #ifdef _WINDOWS google_breakpad::ExceptionHandler eh(dumpLocation.toStdWString(), NULL, minidumpCB, NULL, google_breakpad::ExceptionHandler::HANDLER_ALL); #else google_breakpad::ExceptionHandler eh(dumpLocation.toStdString(), NULL, minidumpCB, NULL, true, NULL); #endif
    #endif }

    接口非常简单,只要定义一个回调函数minidumpCB()。当程序崩溃被捕捉到的时候就会调用这个函数,这里只是输出了mini dump文件保存的位置。如果第一张截图中的红框所示。

    三、dump文件如何利用

     生成的dump文件如何利用?如何转换成我们能看得懂的调用堆栈信息?其实有上面编译出来的两个工具,接下来的工作分三个步骤:

    • 使用dump_syms生成符号表:
      ./dump_syms ~/Test/Caputre > Capture.syms
    • 创建有层次的调试符号文件夹:
      head -n1 Capture.syms  // 查看文件层次
      mkdir -p ./symbols/PanoramaCapture/3EXXXXXX/ //这一步根据上面的输出来
      mv Capture.syms ./symbols/PanoramaCapture/3EXXXXX/ // 将符号文件移动进去
    • 利用minidump_stackwalk分析dump文件:
      ./minidump_stackwalk minidump.dmp ./symbols

     

       最后一步将输出详细的堆栈信息:

      相信有了这些信息,找出代码中潜伏的bug不是什么难事了。而我也正是根据这些信息,成功解决了这次的崩溃问题。再提一句,不管在Windows上还是Mac上,编译Release的时候最好把调试符号文件保存好。这样利用breakpad来分析的时候才能事半功倍,breakpad方才能展现其强大的一面。

    四、参考链接

    1. https://www.jianshu.com/p/295ebf42b05b

    2. https://github.com/google/breakpad

    3. https://groups.google.com/forum/#!topic/google-breakpad-discuss/fierVnIAv1M

    4. https://github.com/gyunaev/google-breakpad-qt

  • 相关阅读:
    JDBC 复习4 批量执行SQL
    JDBC 复习3 存取Oracle大数据 clob blob
    Oracle复习
    Linux命令(1)grep
    JDBC 复习2 存取mysql 大数据
    JDBC 复习1 DBUtil
    php 环境搭建问题
    Windows 批处理 bat 开启 WiFi 菜单选项 设置ID PWD
    Bat 批处理启动和停止Oracle 服务
    docker 学习1 WSL docker ,Windows docker
  • 原文地址:https://www.cnblogs.com/csuftzzk/p/mac_breakpad_qt_dump_debug.html
Copyright © 2011-2022 走看看