代码基于Android 13,代码分支为aosp android-13.0.0_r44;调试机型为Google Pixel5。
欢迎关注微信公众号"ZZH的Android",关注后点击"交流群"菜单加入交流群。
创建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,说明发生了内存异常。
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)
dropbox日志位于/data/system/dropbox
找到对应的日志后adb pull出来解压,也可以得到报错的日志信息。
尝试了使用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行。