前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >BreakPad模拟Android native崩溃

BreakPad模拟Android native崩溃

作者头像
提莫队长
发布2020-06-02 15:29:57
1.5K0
发布2020-06-02 15:29:57
举报
文章被收录于专栏:刘晓杰刘晓杰

1.BreakPad简介

Google breakpad是一个跨平台的崩溃转储和分析框架和工具集合。 Breakpad由三个主要组件:

  • client,以library的形式内置在你的应用中,当崩溃发生时写 minidump文件
  • symbol dumper, 读取由编译器生成的调试信息(debugging information),并生成 symbol file
  • processor, 读取 minidump文件 和 symbol file,生成可读的c/c++ Stack trace.

简单来说就是一个生成 minidump,一个生成symbol file,然后将其合并处理成可读的Stack trace。

2.模拟崩溃

2.1 获取breakpad代码

点击https://chromium.googlesource.com/breakpad/breakpad这个链接,选择左侧的master,下载tgz文件 有些文章说会缺少 linux_syscall_support.h 文件,但是本人实践下来并没有缺少,可能版本更新加进去了,如果没有,可自行查找并添加

2.2 编译

进入源代码根目录,执行以下命令

代码语言:javascript
复制
./configure && make

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

2.3 添加环境变量(MAC)
代码语言:javascript
复制
vim ~/.zshrc
### 在.zshrc文件的末尾添加刚刚生成的文件的路径
export BREAKPAD_HOME=/Users/XXX/Documents/breakpad-refs_heads_master # 这里需要替换自己的breakpad路径
export PATH=$PATH:${BREAKPAD_HOME}/src/processor:${BREAKPAD_HOME}/src/tools/linux/dump_syms # 此处需要注意的是,路径中不要指定具体执行文件名,否则会报找不到相关命令,例如${BREAKPAD_HOME}/src/tools/linux/dump_syms/dump_syms,这样执行dump_syms命令会找不到
### 更新环境变量
source ~/.zshrc
2.4 下载官方Demo并生成so文件和dmp文件

官方Demo的地址在https://github.com/AndroidAdvanceWithGeektime/Chapter01. 一开始本人在编译的时候用的是ndk20的,发现提示C和C++编译器没有设置.经过好几次反复才发现原来是ndk版本太高,导致了用的是clang去编译的,然后就一直抱那个错.后来降低成ndk16就通过了. 还有要注意,用ndk20编译以后,会在libbreakpad模块里面生成externalNativeBuild目录,里面的内容在更换ndk的时候是不会自动更新的,所以需要手动删除,这个问题我也是找了很久.一开始还以为是代码缺了什么配置

2.5 分析dmp文件并生成log日志
代码语言:javascript
复制
minidump_stackwalk /Users/xxx/Desktop/3c22839a-812d-4901-983278b1-de602110.dmp > /Users/xxx/Desktop/1.txt

接下来查看1.txt.得出日志结果过长,大体如下:

代码语言:javascript
复制
Operating system: Android
                  0.0.0 Linux 3.10.90-g01f8576 #1 SMP PREEMPT Tue Oct 25 05:18:00 CST 2016 aarch64
CPU: arm64
     8 CPUs

GPU: UNKNOWN

Crash reason:  SIGSEGV /SEGV_MAPERR
Crash address: 0x0
Process uptime: not available

Thread 0 (crashed)
 0  libbreakpad-native.so + 0x325f4
     x0 = 0x0000000000000000    x1 = 0x0000000000000001
     x2 = 0x0000007f74e64240    x3 = 0x0000000000570000

根据文章Android 平台 Native 代码的崩溃捕获机制及实现 的介绍,我们可知“Crash reason: SIGSEGV /SEGV_MAPERR”代表哪种类型的错误:

代码语言:javascript
复制
SIGSEGV 是当一个进程执行了一个无效的内存引用,或发生段错误时发送给它的信号。
Thread 0 (crashed) //crash 发生时候的线程
0  libnative-lib.so + 0x325f4 //发生 crash 的位置和寄存器信息

有了具体的寄存器信息,我们进行符号解析(注意CPU是arm64)可以使用 ndk 中提供的addr2line来根据地址进行一个符号反解的过程,该工具在

代码语言:javascript
复制
$NDK_HOME/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/bin/aarch64-linux-android-addr2line

进入addr2line所在目录输入(注意地址arm64用aarch64下的工具链解析arm64-v8a下的so文件)

代码语言:javascript
复制
aarch64-linux-android-addr2line -f -C -e /Users/xxx/Documents/AdvanAndroid/BreakpadDemo/app/build/intermediates/transforms/mergeJniLibs/debug/0/lib/arm64-v8a/libbreakpad-native.so 0x325f4

我自己在输入的时候会提示arm-linux-androideabi-addr2line找不到,是因为没有在PATH里面配置,所以我就输入的整个的地址.输出如下

代码语言:javascript
复制
Java_com_example_libbreakpad_BreakPadManager_testBreak
/Users/liuxiaojie/Documents/AdvanAndroid/BreakpadDemo/libbreakpad/.externalNativeBuild/cmake/debug/arm64-v8a/../../../../src/main/cpp/native-lib.cpp:34

之前在ndk切换那里换了个工程,具体地址https://github.com/sunnybird/AdvanAndroid 至此,解析出了native崩溃的原因

参考文献

https://www.jianshu.com/p/295ebf42b05b https://blog.csdn.net/fengyulinde/article/details/81707346 https://www.jianshu.com/p/1687c92efb89

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.BreakPad简介
  • 2.模拟崩溃
  • 参考文献
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档