breakPad 使用

按照张邵文老师在极客专栏的建议,熟悉一下 c 代码的崩溃和分析流程。
breakPad 是谷歌开源的工具,可用来采集和分析 c 代码的崩溃信息。
整体流程不复杂,可分为以下几步:

1.导入邵文老师在 github 的 sample 工程(建议保证环境能够科学上网,要下载不少东西),在手机上运行点击崩溃按钮,手机 sdcard 上新增了崩溃日志。

2.接下来就要使用 minidump_stackwalker 工具来解析崩溃日志了。自己在这一步卡了很长时间:
邵文老师提供的 minidump_stackwalker 工具是在 mac 环境编译出的,我这里是 Ubuntu 环境,不能直接使用,需要自己重新编译出 minidump_stackwalker 工具。一开始时按照 https://github.com/google/breakpad 的方法尝试编译,下载 depot_tools 工具后,fetch breakpad 老是失败,上网搜了不少方法,还是没有解决 fetch breakpad 失败的问题。后来自己想了想,fetch breakpad 实际上就是拉取 breakpad 的源码,既然通过 depot_tools 工具下载失败,直接从 github 上把 breakpad 源码 clone 下来不就好了。从 github 上 clone 下源码后,进入源码目录 cd src 然后 ./configure && make,这时会报错缺少文件third_party/lss/linux_syscall_support.h , 需要在源码根目录下创建 third_party/lss,然后去 https://chromium.googlesource.com/linux-syscall-support/+/refs/heads/master 下载 linux-syscall-support-refs_heads_master.tar.gz 并解压文件到 third_party/lss 目录下,此时再 ./configure && make 即可成功编译。编译成功后在源码根目录下进入 /src/processor目录就能发现 minidump_stackwalker 工具已经生成出来了。

3.使用 minidump_stackwalk crashDump/*.dmp >crashLog.txt 生成堆栈跟踪log。打开文件
后可看到:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Operating system: Android
0.0.0 Linux 3.18.31-perf-g2d4873d #1 SMP PREEMPT Thu Aug 30 02:48:40 CST 2018 aarch64
CPU: arm64
4 CPUs
GPU: UNKNOWN
Crash reason: SIGSEGV /SEGV_MAPERR
Crash address: 0x0
Process uptime: not available
Thread 0 (crashed)
0 libcrash-lib.so + 0x600
x0 = 0x0000007f7de3e300 x1 = 0x0000007fd1f16da4
x2 = 0x006e006512d26880 x3 = 0x0074006100720065
x4 = 0x0000000000000004 x5 = 0x0000007f7de96a00
x6 = 0x0000000066642a85 x7 = 0x0000007fd1f16ef8
x8 = 0x0000000000000000 x9 = 0x0000000000000001
x10 = 0x0000000000430000 x11 = 0x0000000000000000
x12 = 0x000000000000018c x13 = 0x0000000000000062
x14 = 0x0000007f818855d0 x15 = 0x922c5c5cc3324f73
x16 = 0x0000007f7c70efe8 x17 = 0x0000007f7c6fe5ec
x18 = 0x00000000ffffffff x19 = 0x0000007f7de96a00
x20 = 0x0000007f7051fce0 x21 = 0x0000007f7de96a00
x22 = 0x0000007fd1f1707c x23 = 0x0000007f7c807a5c
x24 = 0x0000000000000004 x25 = 0x21634bbd9d3186d1
x26 = 0x0000007f7de96a98 x27 = 0x21634bbd9d3186d1
x28 = 0x0000007fd1f16da0 fp = 0x0000007fd1f16d70
lr = 0x0000007f7c6fe624 sp = 0x0000007fd1f16d50
pc = 0x0000007f7c6fe600
Found by: given as instruction pointer in context
1 libcrash-lib.so + 0x620
fp = 0x0000007fd1f16da0 lr = 0x0000007f7d8b4c14
sp = 0x0000007fd1f16d80 pc = 0x0000007f7c6fe624
Found by: previous frame's frame pointer

由日志可以看出崩溃原因时原因为 libcrash-lib.so 的代码里出现空指针了,此时记录下地址 0X600

4.符号解析,可以使用 ndk 中提供的addr2line来根据地址进行一个符号反解的过程.

1
2
3
arm-linux-androideabi-addr2line -f -C -e sample/build/intermediates/transforms/mergeJniLibs/debug/0/lib/armeabi-v7a/libcrash-lib.so 0x77e
//输出结果如下
Crash()