Breakpad(跨平台crash工具)


  最近海思平台在项目测试过程中,经常出现coredump的问题,尤其是那些的不经常挂的情况,光看日志定位问题真的很难,同时生成的core文件由于各种动态链接和静态链接,分析起来实在是比较困难。为解决coredump问题,有必要提供一个跨平台的crash处理系统,目前已知的支持平台有windows 、Linux、 OS X 、android等,Google自己用的系统Breakpad被广泛的应用于该类的死机场景中。
本章主要学习breakpad的基本概念和移植方法,将用于移植到海思平台上。

1. 简介
  Breakpad是一个库和工具套件可以让你发布的应用程序(把编译器提供的调试信息剥离掉的)给用户,记录了崩溃紧凑的“dump”文件,发送回您的服务器,并从这些minidump产生C和C++堆栈踪迹。Breakpad可以根据请求使没有崩溃的程序也可以写出minidump。目前使用Breakpad的有谷歌浏览器,火狐,谷歌的Picasa,卡米诺,谷歌地球,和其他项目。

Breakpad有三个主要组件:

  客户端是一个库,包含在您的应用程序中。 它可以获取当前线程的状态和当前加载的可执行文件和共享库的ID写转储文件。您可以配置客户端发生了崩溃时写入一个minidump时,或明确要求时。
符号卸载器是一个程序,读取由编译器产生的调试信息,并生成一个使用Breakpad格式的符号文件 。
  该**处理器(minidump processor)**是一个程序,读取一个minidump文件,找到相应的版本的符号文件的(可执行文件和共享库的转储提到的),并产生了一个人可读的C / C + +堆栈跟踪。
小型转储文件格式(即minidump)
  转储文件的格式是由微软开发的类似存储的文件,崩溃便利上传。一个minidump文件包含:

  在创建dump的进程中加载的可执行文件和共享库列表。此列表中包含的特定版本加载的那些文件的文件名和标识符。

  在这个过程中存在的线程列表。对于每个线程转储包括处理器寄存器的状态,线程的堆栈存储器的内容。一般Breakpad客户端没有可用于产生函数名或行号,甚至确定堆栈帧的边界的调试信息,所以这些数据是不可解释的字节流。

  其他收集的有关系统转储信息比如:处理器和操作系统版本,转储的原因,等等。

  Breakpad在所有平台上使用Windows dump文件,而不是传统的core文件,有以下几个原因:

  core文件可能会非常大,不适合在网络上发送给收集器处理。minidump较小,因此它们被设计为使用这种方式。
  core文件格式缺乏文档信息。例如,Linux标准库不描述寄存器如何存储在PT_NOTE段的。
  一个Windows机器上生成一个core dump文件,比起其他机器上生成一个minidump文件,哪个难很难说。
  简化了Breakpad处理器,只支持一种文件格式。
2. 编译Breakpad
下载源码,具体的编译过程请参考breakpad

git clone chrium.googlesource/breakpad/breakpad

编译方法

./configure && make

编译出错

mv f $depbase.Tpo $depbase.Po src/client/linux/crash_generation/crash_generation_clientc:40:10: fatal error: third_party/lss/linux_syscall_support.h: No such file or directory #include "third_party/lss/linux_syscall_support.h" ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cpilation terminated. Makefile:5177: recipe for target 'src/client/linux/crash_generation/crash_generation_client.o' failed make: *** [src/client/linux/crash_generation/crash_generation_client.o] Error 1

  包含了前两者都缺少的一个头文件*linux_syscall_support.h*,该头文件要放在\src\third_party\lss目录下,然后重新编译

  编译完以后会在生成两个可执行文件,分别是src/processor/minidump_stackwalk和src/tools/linux/dump_syms/dump_syms

  生成 src/client/linux/libbreakpad_client.a

3. 实际例子
  编写程序如下breakpad_sample

1 #include "client/linux/handler/exception_handler.h" 2 #include <stdio.h> 3 #include <string.h> 4 5 6 static bool dumpCallback(const google_breakpad::MinidumpDescriptor &descriptor, 7 void *context, 8 bool succeeded) 9 13 14 static void crashHare() 15 19 20 int main(int argc, char *argv[]) 21

编译

g++ g I ../breakpad/src o test breakpad_sample ../breakpad/src/client/linux/libbreakpad_client.a lpthread

运行得到下面的信息

root@100ask:/he/book/hello# ./test Dump path: /he/book/log/b0498cca03411afd49dca885d56aaf.dmp Segmentation fault (core dumped) root@100ask:/he/book/hello#

参看stack 信息

方式一

minidump2core ../log/b0498cca03411afd49dca885d56aaf.dmp > core
gdb ../log/b0498cca03411afd49dca885d56aaf.dmp core
warning: File "/lib/x86_64linuxgnu/libthread_db1.0.so" autoloading has been declined by your `autoload safepath' set to "$debugdir:$datadir/autoload". warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available. Failed to read a valid object file image fr memory. Core was generated by `./test'. Program terminated with signal SIGSEGV, Segmentation fault. #0 0x000055dd66b1f375 in crashHare () at breakpad_sample:17 17 *a = 1; // 放心的奔溃吧 (gdb)

方式二

root@100ask:/he/book/hello# dump_syms ./test | head 1 MODULE Linux x86_64 6BD7C0D9ECCE1FC511E4FBA9D9A13B650 test
mkdir p ./symbols/test/6BD7C0D9ECCE1FC511E4FBA9D9A13B650
dump_syms ./test > ./symbols/test/6BD7C0D9ECCE1FC511E4FBA9D9A13B650/test.sym
minidump_stackwalk ../log/b0498cca03411afd49dca885d56aaf.dmp symbols/

死机信息为

CPU: amd64 family 6 model 142 stepping 12 1 CPU GPU: UNKNOWN Crash reason: SIGSEGV /SEGV_MAPERR Crash address: 0x0 Process uptime: not available Thread 0 (crashed) 0 test!crashHare [breakpad_sample : 17 + 0x4] rax = 0x0000000000000000 rdx = 0x000055dd66d366a0 rcx = 0x0000000000000000 rbx = 0x0000000000000000 rsi = 0x0000000000000000 rdi = 0x000055dd66d366a0 rbp = 0x00007ffe0a737280 rsp = 0x00007ffe0a737280 r8 = 0x0000000000000000 r9 = 0x0000000000000000 r10 = 0x000055dd68c86010 r11 = 0x0000000000000000 r12 = 0x000055dd66b1f220 r13 = 0x00007ffe0a737520 r14 = 0x0000000000000000 r15 = 0x0000000000000000 rip = 0x000055dd66b1f375 Found by: given as instruction pointer in context 1 test!main [breakpad_sample : 29 + 0x5] rbx = 0x0000000000000000 rbp = 0x00007ffe0a737440 rsp = 0x00007ffe0a737290 r12 = 0x000055dd66b1f220 r13 = 0x00007ffe0a737520 r14 = 0x0000000000000000 r15 = 0x0000000000000000 rip = 0x000055dd66b1f446 Found by: call frame info 2 libc.so.6 + 0x21b97 rbx = 0x0000000000000000 rbp = 0x000055dd66b304e0 rsp = 0x00007ffe0a737450 r12 = 0x000055dd66b1f220 r13 = 0x00007ffe0a737520 r14 = 0x0000000000000000 r15 = 0x0000000000000000 rip = 0x00007fcab0eeab97 Found by: call frame info 3 test!crashHare [breakpad_sample : 18 + 0x3] rsp = 0x00007ffe0a737470 rip = 0x000055dd66b1f37e Found by: stack scanning Loaded modules: 0x55dd66b1d000 0x55dd66b35fff test ??? (main) 0x7fcab0b2b000 0x7fcab0cc7fff libm.so.6 ??? 0x7fcab0ec9000 0x7fcab10affff libc.so.6 ??? (WARNING: No symbols, libc.so.6, 4B76CFD3972F3EACFE366DDD07AD902F0) 0x7fcab12ba000 0x7fcab12d0fff libgcc_s.so.1 ??? 0x7fcab14d2000 0x7fcab164afff libstdc++.so.6 ??? 0x7fcab185b000 0x7fcab1874fff libpthread.so.0 ??? 0x7fcab1a7a000 0x7fcab1aa0fff ldlinuxx8664.so.2 ??? 0x7ffe0a789000 0x7ffe0a789fff linuxgate.so ??? 20200810 10:36:22: minidumpc:5061: INFO: Minidump closing minidump

在上面的libc.so.6只给出地址,没给出函数名称,而在Loaded modules中可以看到libc.so.6下的警告No symbols,所以下面给libc.so.6制作一个sym即可,步骤如下:

找到对应的libc.so.6的库文件,取名一定要按照规则去做,比如生成sym文件,一定是二进制程序文件名称加.sym 或者so文件夹.sym,大小写也不能改。

dump_syms libc.so.6 > libc.so.6.sym
root@100ask:/he/book/hello# head n1 libc.so.6.sym MODULE Linux x86_64 4B76CFD3972F3EACFE366DDD07AD902F0 libc.so.6
mkdir p ./symbols/libc.so.6/4B76CFD3972F3EACFE366DDD07AD902F0
mv libc.so.6.sym ./symbols/libc.so.6/4B76CFD3972F3EACFE366DDD07AD902F0/
minidump_stackwalk ../log/b0498cca03411afd49dca885d56aaf.dmp symbols/
Loaded modules: 0x55dd66b1d000 0x55dd66b35fff test ??? (main) 0x7fcab0b2b000 0x7fcab0cc7fff libm.so.6 ??? 0x7fcab0ec9000 0x7fcab10affff libc.so.6 ??? 0x7fcab12ba000 0x7fcab12d0fff libgcc_s.so.1 ??? 0x7fcab14d2000 0x7fcab164afff libstdc++.so.6 ??? 0x7fcab185b000 0x7fcab1874fff libpthread.so.0 ??? 0x7fcab1a7a000 0x7fcab1aa0fff ldlinuxx8664.so.2 ??? 0x7ffe0a789000 0x7ffe0a789fff linuxgate.so ??? 20200810 11:17:27: minidumpc:5061: INFO: Minidump closing minidump



上一篇:OpenMP与MPI混合做方阵向量乘法

下一篇:C++ Windows.h max宏与std::max冲突问题解决


Copyright © 2002-2019 k262电脑网 www.k262.cn 皖ICP备2020016292号
温馨提示:部分文章图片数据来源与网络,仅供参考!版权归原作者所有,如有侵权请联系删除!QQ:251442993 热门搜索 网站地图