一个跨平台的 Crash 状态采集工具,相对 Linux 中的 CoreDump 文件来说,采集的内容更小。
简介
Breakpad 是 Google 开发的一个跨平台 C/C++ Dump 捕获库,其保存文件格式采用微软的 minidump
格式存储,其支持在崩溃时触发,也可以通过手动触发。
主要包含三个组件:
- Client 以 library 形式内置在应用中,当崩溃或者需要时生成 minidump 文件。
- SymbolDumper 读取由编译器生成的调试信息,并保存为 Symbol 文件,格式详见 docs/symbol_files.md 中的介绍。
- Processor 读取 minidump 和 symbol 文件,生成可读的栈信息。
也就是说要在编译阶段生成 Symbol 文件,在运行时生成 minidump 文件,然后根据这两个文件生成调用栈。
minidump
这是由微软开发,用于崩溃上传的文件格式,其包含了:
- 当 dump 生成时,进程中一系列可执行文件以及动态库信息,包括这些文件的文件名和版本号。
- 进程中的线程信息,包括寄存器状态、栈内存等信息。
- 其它相关信息,例如 CPU、OS、dump原因等。
相对 Core 文件来说,minidump 文件会比较小,之所以没有采用 Core 文件,主要还是考虑到跨平台的统一。
底层实现
不同平台上的实现机制略有区别:
Windows
使用微软提供的SetUnhandledExceptionFilter()
方法实现。OS X
通过创建一个线程来监听Mach Exception Port
来实现。Linux
设置一个信号处理器来监听SIGILL
SIGSEGV
等异常信号。
考虑到在崩溃的进程写 minidump 文件是不安全的,三种平台都提供了跨进程的异常处理机制。
示例
其中 ExceptionHandler()
的声明以及参数含义介绍如下:
ExceptionHandler(
const MinidumpDescriptor& descriptor,
FilterCallback filter,
MinidumpCallback callback,
void* callback_context,
bool install_handler,
const int server_fd
);
filter
可选,用来决定是否要写 minidump 文件。callback
可选,写 minidump 文件之后调用的回调函数。install_handler
分成两种场景:A)ture
未捕捉异常抛出时都写 minidump 文件;B)false
明确调用了 WriteMinidump 才会写入。server_fd
当是-1
是则使用同线程模式;否则使用跨线程模式。
注意,在 callback 回调函数中做尽量少的工作,因为此时程序处于不安全状态,一般不允许分配内存或者调用其它共享库,此时 breakpad 提供了一些简单 libc 库的实现,详见 linux_libc_support.h 中的实现。
另外,Breakpad 还提供了一个 HTTP 上传的实现,详见 minidump_upload.cc
的实现。