Android Native Crash捕获和处理

测试异常

测试异常代码如下:

extern "C" JNIEXPORT void JNICALL
Java_io_github_kongpf8848_ndk_demo_MainActivity_testCrash(
        JNIEnv *env,
        jobject clazz) {
    LOGD("testCrash");
    int *a = NULL;
    *a = 1;
}

在Logcat里看到的崩溃日志如下:

2025-04-25 13:59:36.945   420-420   DEBUG                   pid-420                              A  Cmdline: io.github.kongpf8848.ndk.demo
2025-04-25 13:59:36.945   420-420   DEBUG                   pid-420                              A  pid: 31275, tid: 31275, name: pf8848.ndk.demo  >>> io.github.kongpf8848.ndk.demo <<<
2025-04-25 13:59:36.945   420-420   DEBUG                   pid-420                              A        #00 pc 00000000000007b0  /data/app/~~edsCrqKf8ocFdTTuB-HhGQ==/io.github.kongpf8848.ndk.demo-tmYBhQ3bTIp8QDHe-OZ37g==/lib/arm64/libnative-lib.so (Java_io_github_kongpf8848_ndk_demo_MainActivity_testCrash+84) (BuildId: eef6f0072dacd2f172f482c798dee48f95b3ba4b)
2025-04-25 13:59:36.945   420-420   DEBUG                   pid-420                              A        #08 pc 000000000000063e  [anon:dalvik-classes3.dex extracted in memory from /data/app/~~edsCrqKf8ocFdTTuB-HhGQ==/io.github.kongpf8848.ndk.demo-tmYBhQ3bTIp8QDHe-OZ37g==/base.apk!classes3.dex] (io.github.kongpf8848.ndk.demo.MainActivity.onCreate$lambda$0+10)
2025-04-25 13:59:36.945   420-420   DEBUG                   pid-420                              A        #11 pc 00000000000005d4  [anon:dalvik-classes3.dex extracted in memory from /data/app/~~edsCrqKf8ocFdTTuB-HhGQ==/io.github.kongpf8848.ndk.demo-tmYBhQ3bTIp8QDHe-OZ37g==/base.apk!classes3.dex] (io.github.kongpf8848.ndk.demo.MainActivity.$r8$lambda$rUM3fjq6DCdPRch_KZ8iVetBjIM+0)
2025-04-25 13:59:36.945   420-420   DEBUG                   pid-420                              A        #14 pc 000000000000058c  [anon:dalvik-classes3.dex extracted in memory from /data/app/~~edsCrqKf8ocFdTTuB-HhGQ==/io.github.kongpf8848.ndk.demo-tmYBhQ3bTIp8QDHe-OZ37g==/base.apk!classes3.dex] (io.github.kongpf8848.ndk.demo.MainActivity$$ExternalSyntheticLambda0.onClick+4)

使用addr2line获取具体的崩溃信息

addr2line的本地地址如下:
/Users/kongpengfei/Desktop/jack/software/android-sdk-macos/ndk/21.4.7075529/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/bin/aarch64-linux-android-addr2line
执行如下命令:

aarch64-linux-android-addr2line -f -C -e libnative-lib.so 00000000000007b0

输出如下:

Java_io_github_kongpf8848_ndk_demo_MainActivity_testCrash
/Users/kongpengfei/Desktop/jack/workspace/Github/ndk-demo/Demo9/src/main/cpp/native-lib.cpp:19

可以看到具体出错代码的行数为第19行

Breakpad简介

Breakpad‌ 是一个开源的崩溃报告工具,主要用于捕获和分析应用程序中的崩溃信息。在Android平台上,Breakpad 可以帮助开发者捕获和分析Native层(C++)的崩溃信息。

Breakpad is a set of client and server components which implement a crash-reporting system.

构建

  1. 环境搭建

为了方便编译,我选择的是购买腾讯云轻量应用服务器,价格35元/月,配置如下:

系统镜像 地域 配置
Ubuntu 20.04.6 LTS 美国硅谷 CPU - 2核 内存 - 2GB 系统盘 - SSD 云硬盘 60GB
  1. 安装depot_tools
  • 下载depot_tools
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
  • 配置环境变量
vim ~/.bashrc
export depot_tools=/root/depot_tools
export PATH=$depot_tools:$PATH
source ~/.bashrc
  1. 升级gcc到11版本以支持C++20
  • 添加 PPA 仓库
sudo apt update
sudo apt install software-properties-common
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt update
  • 安装gcc 11
sudo apt install gcc-11 g++-11
  • 切换默认gcc版本
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 110
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-11 110
# 选择默认版本
sudo update-alternatives --config gcc
sudo update-alternatives --config g++
  • 验证版本
root@VM-0-9-ubuntu:~# gcc --version
gcc (Ubuntu 11.4.0-2ubuntu1~20.04) 11.4.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
root@VM-0-9-ubuntu:~# g++ --version
g++ (Ubuntu 11.4.0-2ubuntu1~20.04) 11.4.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  1. 获取源码
mkdir breakpad && cd breakpad
fetch breakpad
  1. 编译源码
cd src
./configure && make

编译成功后,输出的主要产物为:

src/libbreakpad.a //用来集成到客户端app中,收集崩溃信息
src/tools/linux/dump_syms/dump_syms //用来提取so文件的符号表信息
src/processor/minidump_stackwalk //用来从.sym符号文件和dump文件中提取崩溃时的堆栈信息

相关链接

https://github.com/acrisci/simple-breakpad-server
https://github.com/mozilla-services/socorro
https://github.com/chromium/crashpad
https://blog.csdn.net/chuyouyinghe/article/details/146377226(编译参考此文章)
https://juejin.cn/post/7354174438005489702
https://firebase.google.com/docs/crashlytics/ndk-reports?hl=zh-cn#upload-symbols-non-gradle-builds
https://juejin.cn/post/6932757164003950599

posted @ 2025-04-25 14:15  南极冰川雪  阅读(22)  评论(0)    收藏  举报