嵌入式linux上Google breakpad编译使用

一、介绍
Breakpad是一个库和工具套件可以让你发布的应用程序(把编译器提供的调试信息剥离掉的)给用户,记录了崩溃紧凑的“dump”文件,发送回您的服务器,并从这些minidump产生C和C++堆栈踪迹。Breakpad可以根据请求使没有崩溃的程序也可以写出minidump。目前使用Breakpad的有谷歌浏览器,火狐,谷歌的Picasa,卡米诺,谷歌地球等目前已知的支持平台有windows 、Linux、 OS X 、Android。简单一点说就是,当你程序挂了,用它可以记录其堆栈信息,这样就很方便的找出奔溃在哪了
Breakpad有四个主要组件:
1).libbreakpad_client.a:客户端,也是要集成到你的程序里的。 它可以获取当前线程的状态和当前加载的可执行文件和共享库的ID写转储文件。需要在奔溃之前创建一个ExceptionHandler,这样你的程序奔溃的时候 才会产生一个有效的 dump文件(这里使用的是minidump,不同与core文件)
2).dump_syms:符号生成器,读取由编译器产生的调试信息,并生成一个使用Breakpad格式的符号文件 。
3).minidump_stackwalk:dump解析器(minidump processor),读取一个minidump文件,根据相应的版本的符号文件,生成堆栈信息。
4).symupload:可以上传奔溃信息。如果你写了一个服务器,可以接收记录它们,当然普通调试就用不到了。
对于不同平台,客户端生成minidump的调用方法会有点差别,默认初始化Breakpad时,安装了一个异常/信号handler,崩溃时可写一个minidump到磁盘。
1)在Windows上,这是通过SetUnhandledExceptionFilter()实现;
2)在 OS X上,这是通过创建一个线程,等待的Mach exception端口
3)在linux上,这是通过安装一个信号handler来应对程序的各种异常情况,如SIGILL,SIGSEGV等。
一旦生成minidump,每个平台上传奔溃信息的方式略有不同,在Windows和Linux上,提供一个单独的函数库(upload)。在OS X上,通过一个单独的进程处理,提示用户是否允许,如果同意这样做则上传文件。

二、下载地址
官方地址这里就不提供了,自己百度,当然那是在你能翻墙的前提下可以去官网下,当然如果不能,那么请在以下地址下载,地址1:已经实验过的可用的完整版本(2017年的),当然随着时间流逝可能就不是最新的了, 地址2可以下载到相对较信道版本,当时截止目前,该版本编译会提示缺少linux_syscall_support.h,你可以从其他地方下载该.h或从地址1下载了替换进去后再编译就OK了
地址1:完整的包 http://download.csdn.net/detail/fword/9878407
地址2:github:https://github.com/bittorrent/breakpad

三、嵌入式linux编译参考:
1).编译
# export CC=/opt/hisi-linux/x86-arm/arm-hisiv400-linux/target/bin/arm-hisiv400-linux-gcc
# export CXX=/opt/hisi-linux/x86-arm/arm-hisiv400-linux/target/bin/arm-hisiv400-linux-g++
# ./configure –host=arm-hisiv400-linux-gnueabi –prefix=/usr/hisiv400/rootfs
# chmod a+x ./configure
# make
# make install
2).完成后 会在 /usr/hisiv400/rootfs 目录的lib/ bin/ include/下生成相应库和工具及头文件

四、直接上实例
环境: linux上使用客户端
文件名:breakpad_sample.cpp

#include "client/linux/handler/exception_handler.h"

static bool dumpCallback(const google_breakpad::MinidumpDescriptor &descriptor,
                         void *context,
                         bool succeeded)
{
    printf("Dump path: %s\n", descriptor.path());
    return succeeded;
}

static void crashHare()
{
    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);
    crashHare();
    return 0;
}

1.注意事项:
回调dumpCallback里做的工作越少越好,因为crash的程序本身就不安全,分配内存或调用另一个库里的函数都是不安全的,使用fork另起个进程来做事才是最安全的. 如果必须在crash时使用回调参考(附件 参考网址4和5),避免直接调用libc

2.编译命令:
root@woozon-PC:breakpad# g++ -g breakpad_sample.cpp -I/usr/hisiv400/rootfs/include/breakpad -L/usr/hisiv400/rootfs/lib -lbreakpad_client -lpthread -o breakpad_sample
注意,这里 -g不要忘了,否则堆栈信息里定位不到具体函数

3.见证奇迹:
下面的每一步如果是做开发的应该都可以看懂,就不详细解释了
拷贝/usr/hisiv400/rootfs/bin/里的所有文件 到你的板子里的/bin/里,这里我将板子nfs挂
/mnt/nfs # cp /mnt/nfs/hisiv400/rootfs/bin/* /bin/
/mnt/nfs # dump_syms ./breakpad_sample > breakpad_sample.sym
/mnt/nfs # head -n1 ./breakpad_sample.sym
MODULE Linux arm C4E8DB657F2EB4C1782CD6BBC6E3DD6D0 breakpad_sample
/mnt/nfs # mkdir -p /tmp/symbols/breakpad_sample/C4E8DB657F2EB4C1782CD6BBC6E3DD6D0
/mnt/nfs # mv ./breakpad_sample.sym /tmp/symbols/breakpad_sample/C4E8DB657F2EB4C1782CD6BBC6E3DD6D0/
/mnt/nfs # ./breakpad_sample
Dump path: /tmp/b2044a06-f906-4a3f-1070d68e-18eb55b3.dmp
Segmentation fault
/mnt/nfs # minidump_stackwalk /tmp/d23f8d5e-5832-45ac-da9a718d-7d847b15.dmp /tmp/symbols
2017-06-15 20:15:02: minidump.cc:4811: INFO: Minidump opened minidump /tmp/d23f8d5e-5832-45ac-da9a718d-7d847b15.dmp
2017-06-15 20:15:02: minidump.cc:4931: INFO: Minidump not byte-swapping minidump
2017-06-15 20:15:02: minidump.cc:5414: INFO: GetStream: type 15 not present
2017-06-15 20:15:02: minidump.cc:5414: INFO: GetStream: type 1197932545 not present
2017-06-15 20:15:02: minidump.cc:5414: INFO: GetStream: type 1197932546 not present
2017-06-15 20:15:02: minidump.cc:2182: INFO: MinidumpModule could not determine version for /mnt/nfs/breakpad_sample
2017-06-15 20:15:02: minidump.cc:2182: INFO: MinidumpModule could not determine version for /lib/libc-2.16.so
2017-06-15 20:15:02: minidump.cc:2182: INFO: MinidumpModule could not determine version for /lib/libpthread-2.16.so
2017-06-15 20:15:02: minidump.cc:2182: INFO: MinidumpModule could not determine version for /lib/libgcc_s.so.1
2017-06-15 20:15:02: minidump.cc:2182: INFO: MinidumpModule could not determine version for /lib/libm-2.16.so
2017-06-15 20:15:02: minidump.cc:2182: INFO: MinidumpModule could not determine version for /lib/libstdc++.so.6.0.19
2017-06-15 20:15:02: minidump.cc:2182: INFO: MinidumpModule could not determine version for /lib/libdl-2.16.so
2017-06-15 20:15:02: minidump.cc:2182: INFO: MinidumpModule could not determine version for /lib/ld-2.16.so
2017-06-15 20:15:02: minidump.cc:2182: INFO: MinidumpModule could not determine version for /mnt/nfs/breakpad_sample
2017-06-15 20:15:02: minidump.cc:2182: INFO: MinidumpModule could not determine version for /lib/libc-2.16.so
2017-06-15 20:15:02: minidump.cc:2182: INFO: MinidumpModule could not determine version for /lib/libpthread-2.16.so
2017-06-15 20:15:02: minidump.cc:2182: INFO: MinidumpModule could not determine version for /lib/libgcc_s.so.1
2017-06-15 20:15:02: minidump.cc:2182: INFO: MinidumpModule could not determine version for /lib/libm-2.16.so
2017-06-15 20:15:02: minidump.cc:2182: INFO: MinidumpModule could not determine version for /lib/libstdc++.so.6.0.19
2017-06-15 20:15:02: minidump.cc:2182: INFO: MinidumpModule could not determine version for /lib/libdl-2.16.so
2017-06-15 20:15:02: minidump.cc:2182: INFO: MinidumpModule could not determine version for /lib/ld-2.16.so
2017-06-15 20:15:02: minidump.cc:5414: INFO: GetStream: type 14 not present
2017-06-15 20:15:02: minidump_processor.cc:152: INFO: Found 2 memory regions.
2017-06-15 20:15:02: minidump_processor.cc:162: INFO: Minidump /tmp/d23f8d5e-5832-45ac-da9a718d-7d847b15.dmp has CPU info, OS info, no Breakpad info, exception, module list, thread list, no dump thread, requesting thread, and no process create time
2017-06-15 20:15:02: minidump_processor.cc:201: INFO: Looking at thread /tmp/d23f8d5e-5832-45ac-da9a718d-7d847b15.dmp:0/1 id 0x5149
2017-06-15 20:15:02: source_line_resolver_base.cc:236: INFO: Loading symbols for module /mnt/nfs/breakpad_sample from memory buffer
2017-06-15 20:15:02: simple_symbol_supplier.cc:196: INFO: No symbol file at /tmp/symbols/libc-2.16.so/D4DD1DB3B93E4BDC3CF81E63D83B8B110/libc-2.16.so.sym
2017-06-15 20:15:02: stackwalker.cc:98: INFO: Couldn’t load symbols for: /lib/libc-2.16.so|D4DD1DB3B93E4BDC3CF81E63D83B8B110
2017-06-15 20:15:02: basic_code_modules.cc:110: INFO: No module at 0xb6dd3000
2017-06-15 20:15:02: basic_code_modules.cc:110: INFO: No module at 0xbebaccc4
2017-06-15 20:15:02: basic_code_modules.cc:110: INFO: No module at 0x1
2017-06-15 20:15:02: postfix_evaluator-inl.h:334: INFO: Identifier lr not in dictionary
2017-06-15 20:15:02: basic_code_modules.cc:110: INFO: No module at 0x0
2017-06-15 20:15:02: basic_code_modules.cc:110: INFO: No module at 0x0
2017-06-15 20:15:02: minidump_processor.cc:326: INFO: Processed /tmp/d23f8d5e-5832-45ac-da9a718d-7d847b15.dmp
Operating system: Linux
0.0.0 Linux 3.10.0_hi3536 #74 SMP Sat Jun 17 13:28:47 CST 2017 armv7l
CPU: arm
ARMv1 ARM part(0x4100c0e0) features: swp,half,thumb,fastmult,vfpv2,edsp,neon,vfpv3,tls,vfpv4,idiva,idivt
4 CPUsUNKNOWNash reason: SIGSEGV
Crash address: 0x0
Process uptime: not available

Thread 0 (crashed)
 0  breakpad_sample!crash() [breakpad_client.cpp : 14 + 0x8]
     r0 = 0xbebacb04    r1 = 0x00000000    r2 = 0x00000001    r3 = 0x00000000
     r4 = 0x00000000    r5 = 0x00000000    r6 = 0x00009a40    r7 = 0x00000000
     r8 = 0x00000000    r9 = 0x00000000   r10 = 0xb6f89000   r12 = 0x00000000
     fp = 0xbebacab4    sp = 0xbebacaa8    lr = 0x00009c88    pc = 0x00009bd0
    Found by: given as instruction pointer in context
 1  breakpad_sample!main [breakpad_client.cpp : 30 + 0x2]
     r4 = 0x00000000    r5 = 0x00000000    r6 = 0x00009a40    r7 = 0x00000000
     r8 = 0x00000000    r9 = 0x00000000   r10 = 0xb6f89000    fp = 0xbebacb74
     sp = 0xbebacab8    pc = 0x00009c88
    Found by: call frame info
 2  libc-2.16.so + 0x17e46
     r4 = 0x00000000    r5 = 0x00000000    r6 = 0x00009a40    r7 = 0x00000000
     r8 = 0x00000000    r9 = 0x00000000   r10 = 0xb6f89000    fp = 0x00000000
     sp = 0xbebacb78    pc = 0xb6cbde48
    Found by: call frame info
 3  breakpad_sample!crash() [breakpad_client.cpp : 15 + 0xa]
     sp = 0xbebacb88    pc = 0x00009be0
    Found by: stack scanning
 4  breakpad_sample!google_breakpad::TypedMDRVA<MDString>::AllocateObjectAndArray(unsigned int, unsigned int) [minidump_file_writer-inl.h : 66 + 0x2e]
     sp = 0xbebacb94    pc = 0x00009a40
    Found by: stack scanning

Loaded modules:
0x00008000 - 0x0001cfff  breakpad_sample  ???  (main)
0xb6ca6000 - 0xb6dc9fff  libc-2.16.so  ???  (WARNING: No symbols, libc-2.16.so, D4DD1DB3B93E4BDC3CF81E63D83B8B110)
0xb6dd7000 - 0xb6deafff  libpthread-2.16.so  ???
0xb6df6000 - 0xb6e11fff  libgcc_s.so.1  ???
0xb6e1b000 - 0xb6e82fff  libm-2.16.so  ???
0xb6e8c000 - 0xb6f43fff  libstdc++.so.6.0.19  ???
0xb6f57000 - 0xb6f58fff  libdl-2.16.so  ???
0xb6f62000 - 0xb6f80fff  ld-2.16.so  ???
2017-06-15 20:15:03: minidump.cc:4783: INFO: Minidump closing minidump

补充:
可以使用下面命令生成一个crash文件然后拷贝到PC上看: 
~# minidump_stackwalk /tmp/d23f8d5e-5832-45ac-da9a718d-7d847b15.dmp /tmp/symbols >/tmp/dump.crash 

实例二、so库文件的dump文件分析
加入你的应用是死再libmx.so库里,那么按照实例一处理你所看到的是如下的现象

Operating system: Linux
                  0.0.0 Linux 3.10.0_hi3536 #77 SMP Tue Jun 27 10:42:15 CST 2017 armv7l
CPU: arm
     ARMv1 ARM part(0x4100c0e0) features: swp,half,thumb,fastmult,vfpv2,edsp,neon,vfpv3,tls,vfpv4,idiva,idivt
     4 CPUs

GPU: UNKNOWN

Crash reason:  SIGFPE
Crash address: 0x10d9
Process uptime: not available

Thread 7 (crashed)
 0  libpthread-2.16.so + 0x103a4
     r0 = 0x00000000    r1 = 0x000010f2    r2 = 0x00000008    r3 = 0xacbff910
     r4 = 0xb6b2f3b0    r5 = 0x9ef15698    r6 = 0x02a5f5a8    r7 = 0x0000010c
     r8 = 0xbe9f4ccc    r9 = 0x00000014   r10 = 0x00000000   r12 = 0x00000008
     fp = 0xacbfed4c    sp = 0xacbfecec    lr = 0xb6b42d84    pc = 0xb099a3a4
    Found by: given as instruction pointer in context
 1  libmx.so + 0x27b382
     sp = 0xacbfecf8    pc = 0xb6a44384
    Found by: stack scanning
 2  libmx.so + 0x35c4f2
     sp = 0xacbfed08    pc = 0xb6b254f4
    Found by: stack scanning
 3  libmx.so + 0x3663ae
     sp = 0xacbfed48    pc = 0xb6b2f3b0
     ...
     Loaded modules:
0x00008000 - 0x00aaffff  breakpad_sample  ???  (main)
0x9db9a000 - 0x9e4e6fff  simhei.ttf  ???
0xb67c9000 - 0xb6b7cfff  libmx.so  ???  (WARNING: No symbols, libnetec.so, E4F19D64548F2D4B67C47B76592E79F70)
 在上面的 libmx.so只给出地址,没给出函数名称,而在Loaded modules中可以看到libmx.so下的警告No symbols,所以下面给libmx.so制作一个sym即可,步骤如下:
    # cd breakpad_sample/lib
     # dump_syms libmx.so >libmx.so.sym
     # head -n1 libmx.so.sym 
     MODULE Linux arm E4F19D64548F2D4B67C47B76592E79F70 libnetec.so
     # mkdir -p /tmp/symbols/libmx.so/E4F1
9D64548F2D4B67C47B76592E79F70/ 
    # mv libmx.so.sym  /tmp/symbols/libmx.so/E4F1
9D64548F2D4B67C47B76592E79F70/
     # minidump_stackwalk /tmp/0300e6cc-21be-4cce-652af6
b4-230197f0.dmp /tmp/symbols/>0300e.crash

这个时候你去看0300e.crash就可以看到libmx.so中的函数名称了,
注意:
取名一定要按照规则去做,比如生成sym文件,一定是 二进制程序文件名称加.sym 或者so文件夹.sym,大小写也不能改。

参考:
1.Google Breakpad 之一,跨平台crash 处理上报系统简介
http://blog.csdn.net/wpc320/article/details/8290501
2.Breakpad 使用方法理解文档
http://blog.csdn.net/vagrxie/article/details/2501244
3.google官方文档:
http://code.google.com/p/google-breakpad/wiki/GettingStartedWithBreakpad
4.some simple reimplementations of libc functions
http://code.google.com/p/google-breakpad/source/browse/trunk/src/common/linux/linux_libc_support.h
5.linux syscall support
http://code.google.com/p/linux-syscall-support/

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值