我的项目介绍

breakpad是google开发的一个跨平台C/C++ dump捕捉开源库,解体文件应用微软的minidump格局存储,也反对发送这个dump文件到服务器,breakpad能够在程序解体时触发dump写入操作,也能够在没有触发dump时被动写dump文件。breakpad反对windows、linux、macos、android、ios等。目前已有Google Chrome, Firefox, Google Picasa, Camino, Google Earth等我的项目应用。

  • 主页:https://chromium.googlesource...
  • 文档:https://chromium.googlesource...
  • GitHub 地址:https://github.com/google/bre...

次要组件

breakpad有三个次要的组件:

  • breakpad client:breakpad的客户端动态库(即:libbreakpad_client.a)。它的次要作用是在程序解体后,接管程序的异样解决,具体来说,它次要做了两方面的事件。

    • 响应程序解体时接管到的signal,包含:SIGSEGV,SIGABRT,SIGFPE,SIGILL,SIGBUS。 (另外两个SIGSTOP,SIGKILL无奈解决)
    • 获取程序解体那一刻的运行时信息,保留为一个minidump格局的文件。
  • symbol dumper:调试信息文件生成程序(即:dump_syms)。次要是用来从可执行程序中提取与符号相干的信息,并保留为一种特定格局的文件。
  • processor module:minidump 处理程序(即:minidump_stackwalk),它的作用就是依据coredump及symbol file,构建出可读的call stack。

下载编译

  • 下载Breakpad源码:git clone https://github.com/google/bre...。
  • 下载Breakpad依赖的三方库 LSS:git clone https://github.com/adelshokhy...),将 LSS 中的linux_syscall_support.h文件放至breakpad/src/third_party/lss/ 目录下。
  • 编译Breakpad:在源目录下执行./configure && make。
libbreakpad_client.a在src/client/linux/ 目录下。dump_syms在src/tools/linux/dump_syms/目录下。minidump_stackwalk在src/processor/目录下。还有一个将minidump转换为core文件的程序minidump-2-core在src/tools/linux/md2core/目录下。

集成breakpad

  • 首先,在程序中援用异样处理程序的头文件。

    #include "client/linux/handler/exception_handler.h"
  • 为了生成minidump文件,咱们须要实例化一个ExceptionHandler对象,并提供一个存储minidump的门路,以及一个回调函数来接管对于已写入的minidump的信息。

    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; }int main(int argc, char* argv[]) {google_breakpad::MinidumpDescriptor descriptor("/tmp");google_breakpad::ExceptionHandler eh(descriptor, NULL, dumpCallback, NULL, true, -1);crash();return 0;}
  • 在编译时须要链接breakpad提供的动态库libbreakpad_client.a,头文件搜寻门路须要蕴含breakpad的src目录。编译运行这个程序,会在/tmp/目录下生成一个minidump文件,并在退出之前打印该文件的门路。
  • 编译命令如下:

    $ g++ -g -I ./ -o breakpad_test test.cpp ./client/linux/libbreakpad_client.a -lpthread -std=c++11
  • PS:回调函数中应该尽可能少的做一些工作。因为当该函数回调时,程序处于不平安状态。从其余函数库分配内存或调用函数可能并不平安。如果你必须要在回调函数中实现一些性能,最平安的操作是forkexec一个新的过程来执行你须要做的任何性能。Breakpad源码中蕴含libc函数的一些简略从新实现,同样,在src/third_party/lss中蕴含一些用于进行Linux零碎调用的函数,应该防止间接调用libc和一些其余的动静库。

发送minidump文件

  • 在理论的应用程序中,能够将minidump文件发送到服务器以便进行后续的剖析和统计工作。
  • Breakpad源码中相干文件在src/common/linux/http_upload.h(HTTP上传)和src/tools/linux/symupload/minidump_upload.cc (minidump上传)。

  

生成符号文件

  • 为了产生有用的堆栈信息,Breakpad要求将二进制文件中的调试符号转换为文本格式的符号文件。
  • 首先,须要确保已应用-g编译程序以蕴含调试符号。
  • 而后,应用dump_syms工具生成文本格式的符号文件。比方程序名为test,则命令如下:

    $ ./dump_syms ./test > test.sym
  • 为了将这些符号与minidump_stackwalk工具一起应用,还须要将它们放在特定的目录构造中。 符号文件的第一行蕴含生成此目录构造所需的信息,比方上述的test.sym可应用如下命令:

    $ head -n1 test.sym MODULE Linux x86_64 6EDC6ACDB282125843FD59DA9C81BD830 test$ mkdir -p ./symbols/test/6EDC6ACDB282125843FD59DA9C81BD830$ mv test.sym ./symbols/test/6EDC6ACDB282125843FD59DA9C81BD830

      

    依据minnidump和symbol生成stack trace

    minidump_stackwalk工具能够提取一个minidump文件及其相应的文本格式符号,并生成可读的堆栈信息。在上述示例中能够应用如下命令生成最初的可读堆栈信息文件:

    $ ./minidump_stackwalk xxxx.dmp ./symbols > dmp_info.txt

      

    应用总结

  • 应用-g选项编译程序。
  • 应用dump_syms工具提取上一步生成的可执行文件中的符号,而后将符号文件放到指定目录下。
  • 去掉-g选项从新编译程序。
  • 待程序产生解体时生成dmp文件。
  • 应用minidump_stackwalk工具将dmp文件转换成可读的堆栈信息文件。

以上,应用自动化脚本更简略。