共计 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:回调函数中应该尽可能少的做一些工作。因为当该函数回调时,程序处于不平安状态。从其余函数库分配内存或调用函数可能并不平安。如果你必须要在回调函数中实现一些性能,最平安的操作是
fork
和exec
一个新的过程来执行你须要做的任何性能。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 文件转换成可读的堆栈信息文件。
以上,应用自动化脚本更简略。