Android收藏集

APP崩溃之BreakPad捕获异常

2019-07-20  本文已影响16人  PuHJ

一、简介

在开发APP时一定会遇到程序异常退出的情况,有时相对于解决问题,发现定位问题更加的困难和重要。这里就需要一个功能强大的异常捕获框架——BreakPad

Android的崩溃大体可分为以下三种:

对于以上三种情况,Native的异常捕获定位比较困难。需要对操作系统等底层有很深入的了解,以及一些极端情况的考虑(如日志生成失败导致的破坏了原来的崩溃现场)。才能制定一个优秀的异常捕获框架,但这也让BreakPad的代码量增加了。

二、window下使用BreakPad

1)、下载BreakPad源码

1、利用git等方式下载BreakPad源码,需要使用该编译源码生成工具,以及用到以上的JNI文件。
2、下载的头文件中会缺少一个文件夹,会导致配置编译的时候出现错误,这个需要手动的下载。这个可以在GitHub中下载
缺少的文件

2)、配置编译源码

1、环境准备

需要准备Linux系统和Make,我这里用的是ubantu-16-04-3版本、Make-4.1、XShell、共享工具

2、编译

3)、使用Breakpad

下载的BreakPad源码会有JNI文件,利用该文件单独放置一个模块中,官方的例子中使用的是makefile,这里改用的是make编译。可以直接将GitHub中的breakpad下载使用。

public class BreakpadInit {
    static {
        System.loadLibrary("breakpad-core");
    }

    public static void initBreakpad(String path){
        initBreakpadNative(path);
    }

    private static native void initBreakpadNative(String path);
}

接下来使用breakpad就很简单了,直接在初始化BreakPad库的时候配置一个文件夹,该文件夹是存放之后生成的日志文件。

三、定位问题

#include <stdio.h>
#include <jni.h>


/**
 * 引起 crash
 */
void Crash() {
    volatile int *a = (int *) (NULL);
    *a = 1;
}

extern "C"
JNIEXPORT void JNICALL
Java_com_dodola_breakpad_MainActivity_crash(JNIEnv *env, jobject obj) {
    Crash();
}

奔溃后,取出生成的奔溃日志。我这里的日志名改成了t.dmp

Operating system: Android
                  0.0.0 Linux 4.4.21-perf-g6679372 #1 SMP PREEMPT Tue Jan 23 00:40:47 CST 2018 aarch64
CPU: arm64
     8 CPUs

GPU: UNKNOWN

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

Thread 0 (crashed)
 0  libcrash-lib.so + 0x5e0
     x0 = 0x0000007f7463e180    x1 = 0x0000007ffe09eb34
     x2 = 0x0000000000000000    x3 = 0x0000007f74696a00
     x4 = 0x0000007ffe09efa8    x5 = 0x0000007f58bbf506
     x6 = 0x00000000001b9ded    x7 = 0x0000000012c7cce8
     x8 = 0x0000000000000001    x9 = 0x0000000000000000
    x10 = 0x375abb98f10f9542   x11 = 0x0000000000000000
    x12 = 0x0000000000000000   x13 = 0x0000000000430000
    x14 = 0x0000000000000000   x15 = 0x0000007f745fc7d0
    x16 = 0x0000007f73024fe8   x17 = 0x0000007f730145cc
    x18 = 0x00000000000000af   x19 = 0x0000007f74696a00
    x20 = 0x0000007f7404d350   x21 = 0x0000007f74696a00
    x22 = 0x0000007ffe09eddc   x23 = 0x0000007f58bbf506
    x24 = 0x0000000000000004   x25 = 0x375abb98f10f9542
    x26 = 0x0000007f74696a98   x27 = 0x0000007f74690600
    x28 = 0x375abb98f10f9542    fp = 0x0000007ffe09eb10
     lr = 0x0000007f73014604    sp = 0x0000007ffe09eaf0
     pc = 0x0000007f730145e0
    Found by: given as instruction pointer in context
 1  libcrash-lib.so + 0x600
     fp = 0x0000007ffe09ebf8    lr = 0x0000007f58cfda94
     sp = 0x0000007ffe09eb20    pc = 0x0000007f73014604
    Found by: previous frame's frame pointer
 2  base.odex + 0x2f9a90
     fp = 0x0000007ffe09ecf0    lr = 0x0000007f7405af54
     sp = 0x0000007ffe09ec08    pc = 0x0000007f58cfda94
    Found by: previous frame's frame pointer

这里面有奔溃的位置:libcrash-lib.so + 0x5e0
使用的CPU架构:arm64

对于Crash Reason可以参考如下对应表:
Crash code对应表

对应上面的Native崩溃,可以看出崩溃的原因是“地址无效”导致的。

这里执行的命令:

aarch64-linux-android-addr2line.exe -f -C -e 
D:\F\project\self\github\AndroidAdvanceWithGeektime\Chapter01\sample\build\intermediates\transforms\mergeJniLibs\debug\0\lib\arm64-v8a\libcrash-lib.so 0x5e0

这里需要错误的so文件和crash.txt中报错对的偏移地址 0x5e0和addr2line.exe


addr2line

这里就可以定位到是这个so库中的Crash方法、第十行出现的问题。

上一篇 下一篇

猜你喜欢

热点阅读