使用breakpad收集native奔溃日志及dump解析

本文是学习使用breakpad的一个总结,在这过程中看了很多博客,但是相对有用的有以下几篇:

  1. Android使用Google Breakpad进行崩溃日志管理
  2. breakpad的正确编译和常规用法
  3. Google Breakpad 学习笔记

环境:win10 linux 子系统,ubuntu 20,android-ndk-r20

一、源码编译

先到github下载google/breakpad的源码,在ubuntu下编译。
总共遇到了三个问题(实际算两个问题),基本没什么大问题即可编译成功。

1.1 文件结尾问题

用windows的git clone代码有这个文件结尾的问题,导致各种失败。直接在ubuntu中clone代码可以避免这种麻烦。

1.2 找不到文件:third_party/lss/linux_syscall_support.h

fatal error: third_party/lss/linux_syscall_support.h: No such file or directory

去这个仓库linux-syscall-support下载并丢到对应目录即可

1.3 "rsp"过时导致失败

下载2这个文件后编译报错:
./src/third_party/lss/linux_syscall_support.h:2146:75: error: listing the stack pointer register ‘rsp’ in a clobber list is deprecated [-Werror=deprecated]
2146 | : “rsp”, “memory”, “r8”, “r10”, “r11”, “rcx”);

根据提示,定位到代码,把"rsp"从列表中删除即可

1.4 编译结果

  1. client: /src/client/linux/libbreakpad_client.a,此文件可以编译进android 的app,完成native crash的捕捉和生成minidump文件;
  2. dump_syms: /src/tools/linux/dump_syms,用于提取so库的sym符号文件;
  3. minidump_stackwalk: /src/processor/minidump_stackwalk,用于将.dmp minudump文件和.sym文件合成可读的堆栈信息;

二、接入breakpad(奔溃收集堆栈信息)

可参考Android使用Google Breakpad进行崩溃日志管理

三、解析dump

linux 环境下进行

3.1 准备工作

将以下文件拷贝到一个目录(如果不拷贝到同一个目录则需要在不同的目录执行):

  1. /src/tools/linux/dump_syms/dump_syms
  2. /src/processor/minidump_stackwalk
  3. 准备带符号表的so(build\intermediates\CXX\debug)
  4. 准备收集到的奔溃堆栈文件(如:fde85952-3123-497b-83708b84-58dd1e16.dmp)

3.2 解析dump

假设so:libbreakpad

# 1.dump_syms 提取特定so库的符号信息
./dump_syms libbreakpad.so > libbreakpad.so.sym
head -n1 libbreakpad.so.sym
# MODULE Linux arm64 659648E1F0DF9DFFD7E92A56FED08B930 libbreakpad.so
# 2.根据上面的生成目录结构,libbreakpad.sym移动到该目录
mkdir -p ./symbol/libbreakpad.so/8D8810A6193BEF7CE4FA900D3945461A0
mv libbreakpad.so.sym ./symbol/libbreakpad.so//8D8810A6193BEF7CE4FA900D3945461A0/# 3.调用minidump_stackwalk命令,将dmp文件和sym文件合成可读的crashinfo.txt
./minidump_stackwalk be8144d6-9733-4d78-1841a6aa-e70a16f7.dmp  ./symbol > crashinfo.txt

经过以上步骤可以得到堆栈信息,并且能看到奔溃所在的代码行

Operating system: Android0.0.0 Linux 4.4.126 #1 SMP PREEMPT Thu Oct 21 15:23:47 CST 2021 aarch64
CPU: arm646 CPUsGPU: UNKNOWNCrash reason:  SIGSEGV /SEGV_MAPERR
Crash address: 0x0
Process uptime: not availableThread 0 (crashed)0  libbreakpad.so!Java_com_bottle_breakpad_Breakpad_testCrash [breakpad.cpp : 48 + 0x0]x0 = 0x00000076d403e180    x1 = 0x0000007ffca69c74x2 = 0x0000000000000000    x3 = 0x00000076d4095a00x4 = 0x0000007ffca6a0e8    x5 = 0x00000076baa1b45bx6 = 0x0000000000000000    x7 = 0x0000000000000000x8 = 0x0000000000000000    x9 = 0x0000000000000001x10 = 0x0000000000430000   x11 = 0x00000076d8349b30x12 = 0x00000000000000c4   x13 = 0x0000000000000072x14 = 0x00000076d7e9e170   x15 = 0xa2f74dbe36d6b483x16 = 0x00000076d4bcf5b0   x17 = 0x00000076d29d93f8x18 = 0x0000000c00000000   x19 = 0x00000076d4095a00x20 = 0x00000076d3aa8cb0   x21 = 0x00000076d4095a00x22 = 0x0000007ffca69f1c   x23 = 0x00000076baa1b45bx24 = 0x0000000000000004   x25 = 0x4238bf38fb418304x26 = 0x00000076d4095a98   x27 = 0x4238bf38fb418304x28 = 0x0000000000000001    fp = 0x0000007ffca69d38lr = 0x00000076bacc9004    sp = 0x0000007ffca69c60
.......

如果没有经过步骤1,2,没生成符号表,直接使用第三步解析dump。则不能直接定位到代码行,此时需要addr2line来定位

 ./minidump_stackwalk be8144d6-9733-4d78-1841a6aa-e70a16f7.dmp > nosymbol_crashinfo.txt
Operating system: Android0.0.0 Linux 4.4.126 #1 SMP PREEMPT Thu Oct 21 15:23:47 CST 2021 aarch64
CPU: arm646 CPUsGPU: UNKNOWNCrash reason:  SIGSEGV /SEGV_MAPERR
Crash address: 0x0
Process uptime: not availableThread 0 (crashed)0  libbreakpad.so + 0x24400x0 = 0x00000076d403e180    x1 = 0x0000007ffca69c74x2 = 0x0000000000000000    x3 = 0x00000076d4095a00x4 = 0x0000007ffca6a0e8    x5 = 0x00000076baa1b45bx6 = 0x0000000000000000    x7 = 0x0000000000000000x8 = 0x0000000000000000    x9 = 0x0000000000000001x10 = 0x0000000000430000   x11 = 0x00000076d8349b30x12 = 0x00000000000000c4   x13 = 0x0000000000000072x14 = 0x00000076d7e9e170   x15 = 0xa2f74dbe36d6b483x16 = 0x00000076d4bcf5b0   x17 = 0x00000076d29d93f8x18 = 0x0000000c00000000   x19 = 0x00000076d4095a00x20 = 0x00000076d3aa8cb0   x21 = 0x00000076d4095a00x22 = 0x0000007ffca69f1c   x23 = 0x00000076baa1b45bx24 = 0x0000000000000004   x25 = 0x4238bf38fb418304x26 = 0x00000076d4095a98   x27 = 0x4238bf38fb418304x28 = 0x0000000000000001    fp = 0x0000007ffca69d38lr = 0x00000076bacc9004    sp = 0x0000007ffca69c60pc = 0x00000076d29d9400

3.3 address2line

address2line在ndk中,如:

E:\SDK\android-ndk-r20\toolchains\aarch64-linux-android-4.9\prebuilt\windows-x86_64\bin\aarch64-linux-android-addr2line.exe

使用步骤:

# cd到address2line所在目录
# NDK r20
cd E:\SDK\android-ndk-r20\toolchains\aarch64-linux-android-4.9\prebuilt\windows-x86_64\bin
aarch64-linux-android-addr2line.exe -e E:\repository\breakpad-demo\out\libbreakpad.so 0x58458# 输出
E:/repository/breakpad-demo/BreakpadDemo/breakpad/src/main/cpp/breakpad.cpp:48

可以看到使用addr2line和前面得到的是一致的。到此,breakpad编译,接入,解析dump一整个流程已经完成。但是解析dump使用起来还是比较复杂,可以写一个 linux 的 shell 脚本简化工作。

3.4 使用脚本解析dump

整个流程相对复杂,手工操作比较浪费时间,程序员不应该把时间浪费在重复的工作上。这时候脚本就派上用场,可以写一个脚本,把整个流程抽象为一个脚本,脚本输入是dump文件的路径和输出的解析后的文件路径。只要拷贝这个脚本,修改breakpad和带符号表的so的路径即可快速地实现dump解析。甚至可以部署一个http服务,用户上传dump文件和so,然后返回解析的dump文件。测试可以使用这种方法,快速定位奔溃位置。

#!/bin/sh
# 在linux环境下执行,如在windows,可装一个Linux子系统
# 接收两个参数:
# $1=dump文件
# $2=输出的文件
# path/to/dump.sh be8144d6-9733-4d78-1841a6aa-e70a16f7.dmp CrashInfo.txt# TODO1 修改指你的so目录,注意是debug的
lib_path=/path/to/your/so
# TODO2 修改指向dump_syms的所在目录
dump_syms=/path/to/your/dump_syms
# TODO3 修改指向minidump_stackwalk的所在目录
minidump=/path/to/your/minidump_stackwalk
echo pwd=$(pwd)
echo so path=$lib_path
echo dump_syms=$dump_syms
echo minidump_stackwalk=$minidump# 定义一个函数,用来解析符号表
symbolFun() {echo "parameter 1 is $1"libsym=$1.symecho $libsym$dump_syms $lib_path/$1 > $libsymlibsymDir=$(head -n1 $libsym)# 截取目录名称echo $libsymDirlibsymDir2=${libsymDir#*"MODULE Linux arm "}echo $libsymDir2libsymDir3=${libsymDir2% $1}echo $libsymDir3mkdir -p ./symbol/$1/$libsymDir3mv $libsym ./symbol/$1/$libsymDir3/
}
symbolFun libxyz1.so
symbolFun libxyz2.so
symbolFun libxyz3.so
...# 开始解析dump
$minidump $1  ./symbol > $2

四、另一种解析dump的方法

Android studo安装目录自带了一份minidump_stackwalk自带的minidump_stackwalk。本机地址为:
C:\ProgramFiles\android-studio\plugins\android-ndk\resources\lldb\bin\minidump_stackwalk.exe

C:\ProgramFiles\android-studio\plugins\android-ndk\resources\lldb\bin\minidump_stackwalk.exe E:\repository\breakpad-demo\dump\be8144d6-9733-4d78-1841a6aa-e70a16f7.dmp > E:\repository\breakpad-demo\dump\native_crashinfo.txt

同样可以得到堆栈信息,由于没有使用符号表,所以使用addr2line继续定位到代码行

五、总结

不管使用何种方法,都需要带符号表的so,这个需要在编译库的时候保存下来。这就需要每个放行的apk都要保留一份带符号的so。记住每个步骤,每个工具,是一件复杂的事情,脚本可以将复杂问题简单化,只需要一次编写就可以避免记住那么多工具、指令,相对于学习脚本的这点付出,是非常值得的。

使用breakpad收集native奔溃日志及dump解析相关推荐

  1. Android ExceptionThrowable 常见异常和解决方法 奔溃日志上报 monkey异常修改

    java将所有的错误封装为一个对象,其根本父类为Throwable, Throwable有两个子类:Error和Exception. 注意:异常和错误的区别:异常能被程序本身可以处理,错误是无法处理. ...

  2. 使用DDMS抓取安卓APP的奔溃日志

                                   使用DDMS抓取安卓APP的奔溃日志 一.什么是DDMS DDMS 的全称是Dalvik Debug Monitor Service,是 ...

  3. Android之抓取adb logcat全日志后怎么过滤掉只包含当前app进程的日志(一般抓启动app奔溃日志)

    1 .问题 有时候我们启动APP的时候,APP奔溃,在android studio里面日志可能冲掉,或者是云平台的手机安装的app,根本就没有android stduio,那我们用什么办法快速知道启动 ...

  4. Android之看起来像奔溃了但是没有发现奔溃日志

    1.问题 startActivity之后,然后finish,发现输入密码文本框密码没了,以为奔溃了,但是没有发现奔溃日志 2.思考 我想是不是因为调用蓝牙API结束后还有哪些没有写,往第三方API思考 ...

  5. android奔溃日志手机查看

    开原地址:https://github.com/simplepeng/SpiderMan SpiderMan能为您做的事: 在Android手机上显示闪退崩溃信息,直接分享给相关开发人员! 再也不用担 ...

  6. 5.NDK Android jni开发 异常处理 native奔溃解决(相机图片美化)

    http://www.droidsec.cn/常见android-native崩溃及错误原因/ https://blog.csdn.net/ddxxii/article/details/8478111 ...

  7. Android 捕获异常,上报异常日志,捕获奔溃日志,bugly使用实例

    1.登录腾讯bugly平台创建应用 腾讯Bugly - 一种愉悦的开发方式 _android anr_android anr分析_iOS崩溃日志分析平台 2.1加载依赖 /*崩溃处理 */ imple ...

  8. ios奔溃日志 异常代码 0x8badf00d

    Termination Reason: Namespace SPRINGBOARD, Code 0x8badf00d 异常代码 0x8badf00d 指示应用程序已终止的 iOS 因为看门狗超时发生. ...

  9. android 抓取native层奔溃

    使用android的breakpad工具 使用这个工具需要下载Breakpad的源码,然后进行编译,编译之后会生成两个工具 我们使用这两个工具来解析奔溃的位置.这里我们可以下载已经编译好的工具 下载地 ...

最新文章

  1. 笔记-信息化与系统集成技术-国务院关于印发新一代人工智能发展规划的通知...
  2. 浅谈缓存最终一致性的解决方案
  3. 在惨遭勒索病毒攻击之后,微软呼吁重新制定“数字日内瓦公约”
  4. Bootstrap-CSS-代码
  5. [BZOJ4913][SDOI2017]遗忘的集合
  6. sqoop 使用笔记
  7. CarSim仿真快速入门(十四)—CarSim-Simulink联合仿真
  8. 一款开源的 macOS 外接显示器必备工具
  9. 字字珠玑,证监会84问小米如何反击?
  10. 图解密码学密钥的分配方式
  11. 隔离模块介绍-隔离电源模块
  12. 微信签到积分换卷小程序(完整前后台)
  13. 别用微信文件传输助手了,这6款在线工具真香
  14. 淘宝天猫各平台APP端页面详情api接口调用
  15. Win7系统声卡驱动正常但电脑没声音 扬声器和线路输入“未插入”
  16. Java引入第三方包
  17. 两种经过验证的设计相结合:带有低温探针台的 8425 型直流霍尔系统
  18. linux 分卷压缩命令
  19. 五分钟带你了解面向对象的四大基本特征
  20. 《kdb+中文教程》介绍

热门文章

  1. 阿里云容器镜像服务(Docker Registry)
  2. 怎么注册公司邮箱?公司邮箱注册流程介绍
  3. cobol .cpy文件_Visual COBOL R3:“使传统的COBOL能够部署在JVM或.NET上”。
  4. Android 自定义dialog 设置宽度的问题
  5. 在linux中at 调度出错,Linux 技巧: 用cron 和at 调度作业
  6. 软件观念革命:交互设计精髓_万字干货,交互设计精髓105条设计原则(附中英PDF资料)...
  7. 若依ruoyi框架实现单点登录或者接入统一认证
  8. 【软件质量】软件复杂性
  9. 【项目实战】正确辨析蓝绿部署、金丝雀发布(灰度发布)、滚动发布、A/B测试
  10. 天线巴伦制作和原理_巴伦的原理、设计、制作