Android Native Crash 问题分析第一弹

1、环境

代码基于Android 13,代码分支为aosp android-13.0.0_r44;调试机型为Google Pixel5。

欢迎关注微信公众号"ZZH的Android",关注后点击"交流群"菜单加入交流群。

2、获取Native Crash日志

2.1 Native Crash Demo

创建packages/apps/NativeCrashDemo目录,然后编写Android.bp文件和main.cpp文件,如下:

packages/apps/NativeCrashDemo/Android.bp

cc_binary {
    name: "native_crash_demo",

    srcs: ["main.cpp"],

    shared_libs: [
        "liblog",
        "libutils",
        "libcutils",
    ],

    compile_multilib: "first",

    cflags: [
        // 这里-O0和-g必须有,这个是将调试信息
        // 打包进编译产物,否则后续无法精确定位
        "-O0",
        "-g",
        "-Wall",
        "-Wextra",
        "-Werror",
        "-Wno-unused-parameter",
    ],
}

packages/apps/NativeCrashDemo/main.cpp

#define LOG_TAG "native_crash_demo"
//#define LOG_NDEBUG 0

#include 

// 定义一个类,后面创造空指针异常
class CrashDemo {
public:
    void setA(int a) {
        this->a = a;
    }
private:
    int a;
};

int main(int argc, char** argv) {
    // 这里创建一个空指针用来调用类的函数
    CrashDemo* crashDemoPtr = NULL;
    crashDemoPtr->setA(5);
    return 0;
}

编译运行

source build/envsetup.sh
lunch aosp_redfin-userdebug
make native_crash_demo

编译完成后将可执行文件push到设备

adb root && adb remount
adb push out/target/product/redfin/system/bin/native_crash_demo /system/bin/

运行可执行文件native_crash_demo

zzh@ubuntu:~/work/aosp/android-13.0.0_r44$ adb shell
redfin:/ # native_crash_demo                                                                                                                                                                 
Segmentation fault 
139|redfin:/ # 

如上,在执行完native_crash_demo后输出了Segmentation fault,说明发生了内存异常。

2.2 获取日志

2.2.1 tombstones

tombstones日志生成目录在/data/tombstones/,上面的程序执行完后,生成的tombstones文件如下:

redfin:/data/tombstones # ls -lh
total 48K
-rw-rw---- 1 tombstoned system 30K 2024-01-09 22:44 tombstone_00
-rw-rw---- 1 tombstoned system 12K 2024-01-09 22:44 tombstone_00.pb

我们直接使用文本工具打开tombstone_00文件就能看到基本的报错信息,如下:

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'Android/aosp_redfin/redfin:13/TQ2A.230505.002.A1/eng.zzh.20231224.215123:userdebug/test-keys'
Revision: 'MP1.0'
ABI: 'arm64'
Timestamp: 2024-01-09 22:44:00.377867873+0800
Process uptime: 1s
// 报错的可执行文件
Cmdline: native_crash_demo
// 进程号、线程号、进程名称
pid: 4031, tid: 4031, name: native_crash_de  >>> native_crash_demo <<<
uid: 0
// Signal类型,出现SEGV_MAPERR一般都是空指针问题
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0000000000000000
// 这里列出了具体的崩溃原因,确实是空指针
Cause: null pointer dereference
    x0  0000000000000000  x1  0000000000000005  x2  0000007fd6916e58  x3  0000007fd6916e18
    x4  0000007ae797d080  x5  0000000001414d4c  x6  2f6d65747379732f  x7  6974616e2f6e6962
    x8  0000000000000005  x9  0000000000000000  x10 000000000000105f  x11 0000000000000004
    x12 0000000000000016  x13 0000000000000002  x14 047de045f78db61d  x15 0000000000000023
    x16 0000007ae591fe08  x17 0000007ae89c5a48  x18 0000007ae8690000  x19 000000559e3e4054
    x20 0000007fd6916e48  x21 0000007fd6916e58  x22 0000000000000001  x23 0000000000000000
    x24 0000000000000000  x25 0000000000000000  x26 0000000000000000  x27 0000000000000000
    x28 0000000000000000  x29 0000007fd6916dd0
    lr  000000559e3e4088  sp  0000007fd6916da0  pc  000000559e3e40ac  pst 0000000080001000

// 这里是堆栈信息
backtrace:
      // 这两行已经大致可以看到出错的地方是CrashDemo::setA(int)函数执行时报错
      // pc后面就是后面使用addr2line时要传入的地址
      #00 pc 00000000000010ac  /system/bin/native_crash_demo (CrashDemo::setA(int)+20) (BuildId: 12629a3544c4350f43d182391e6fea4b)
      #01 pc 0000000000001084  /system/bin/native_crash_demo (main+48) (BuildId: 12629a3544c4350f43d182391e6fea4b)
      #02 pc 000000000004a1f4  /apex/com.android.runtime/lib64/bionic/libc.so (__libc_init+96) (BuildId: 4e07915368c859b1910c68c84a8de75f)

2.2.2 dropbox日志

dropbox日志位于/data/system/dropbox
找到对应的日志后adb pull出来解压,也可以得到报错的日志信息。

3、使用addr2line定位分析

尝试了使用ubuntu自带的addr2line以及Android Studio Ndk里的addr2line,均无法定位到具体的代码行数。。

使用ubuntu的addr2line工具

zzh@ubuntu:~/work/aosp/android-13.0.0_r44$ addr2line -e ./out/target/product/redfin/symbols/system/bin/native_crash_demo 00000000000010ac -f -a -p -C
0x00000000000010ac: addr2line: DWARF error: invalid or unhandled FORM value: 0x23
CrashDemo::setA(int) at main.cpp:?

使用Android Studio Ndk里带的addr2line工具

zzh@ubuntu:~/work/aosp/android-13.0.0_r44$ /home/zzh/Android/Sdk/ndk/22.1.7171670/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-addr2line  -e ./out/target/product/redfin/symbols/system/bin/native_crash_demo 00000000000010ac -f -a -p -C
/home/zzh/Android/Sdk/ndk/22.1.7171670/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-addr2line: ./out/target/product/redfin/symbols/system/bin/native_crash_demo: don't know how to handle section `.relr.dyn' [0x      13]
0x00000000000010ac: /home/zzh/Android/Sdk/ndk/22.1.7171670/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-addr2line: Dwarf Error: found dwarf version '5', this reader only handles version 2, 3 and 4 information.
CrashDemo::setA(int) at main.cpp:?

最后发现需要使用aosp自带的addr2line工具才行,android-13.0.0_r44的源码中addr2line位于如下目录:

./prebuilts/clang/host/linux-x86/llvm-binutils-stable/llvm-addr2line
./prebuilts/clang/host/linux-x86/clang-r450784d/bin/llvm-addr2line

用如上工具分析,输出如下:

zzh@ubuntu:~/work/aosp/android-13.0.0_r44$ ./prebuilts/clang/host/linux-x86/llvm-binutils-stable/llvm-addr2line -e ./out/target/product/redfin/symbols/system/bin/native_crash_demo 00000000000010ac -f -a -p -C
0x10ac: CrashDemo::setA(int) at packages/apps/NativeCrashDemo/main.cpp:9

这里可以看出报错在main.cpp的第9行。

你可能感兴趣的:(Android系统开发,#,Android车载开发,性能优化,android,native,Crash,性能优化,Performance,addr2line,dropbox,tombstones)