关于linux:Linux程序中集成breakpad

34次阅读

共计 3063 个字符,预计需要花费 8 分钟才能阅读完成。

我的项目介绍

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 文件转换成可读的堆栈信息文件。

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

正文完
 0