Skip to content

native-crash-breakpad ​

1. 实验目标 ​

演示 Android Native 层崩溃的完整链路(对应 docs/07-performance-testing-debug/12):

  • 在 native 代码里故意触发 SIGSEGV(空指针解引用),观察 tombstone 生成
  • 用带符号的 .so 配合 ndk-stack / minidump_stackwalk(Breakpad)把地址还原成函数名 + 行号
  • 对照 Java 层 UncaughtExceptionHandler 与 native 崩溃的捕获差异

本实验给出 native 触发代码 + 还原命令(见「7. 关键源码」);完整编译需要 NDK 工程,暂不接入 Android Host 构建。

2. 工程要点 ​

  • Native 崩溃由 signal 投递:SIGSEGV(11) / SIGABRT(6) / SIGBUS(7);debuggerd 抓取生成 /data/tombstones/tombstone_xx
  • tombstone 只含偏移地址,需 (objdump/ndk-stack) + 带符号 so 还原符号
  • Breakpad:编译期注入 libbreakpad,崩溃时写 minidump,离线用 minidump_stackwalk 还原(适合发版后远程堆栈)

3. 运行方式 ​

bash
# 1) 触发并抓 tombstone(native 空指针)
adb shell kill -11 <pid>        # 或运行触发 SIGSEGV 的 demo
adb shell cat /data/tombstones/tombstone_00 | head -60

# 2) 用 ndk-stack 还原(需 NDK 与未 strip 的 so)
ndk-stack -sym app/build/intermediates/merged_native_libs/debug/out/lib/arm64-v8a/ \
          -dump tombstone_00

# 3) Breakpad 离线还原
minidump_stackwalk crash.dmp symbols/ > crash.txt

4. 预期现象 ​

  • SIGSEGV 后进程退出,logcat 出现 Fatal signal 11 (SIGSEGV),/data/tombstones 新增一条
  • tombstone 中 #00 pc 0000xxxx 经 ndk-stack 还原为 native_crash_demo.cpp:42(函数 + 行号)
  • 未带符号的 so 只能看到地址,看不到函数名 → 强调发版保留 unstripped .so

5. 常见误区 ​

误区实际情况
Java 的 try/catch 能兜住 native 崩溃不能,native 崩溃直接 signal,绕开 JVM 异常体系
发版 so 带符号更方便排查发版应 strip,单独归档 unstripped so 供还原(体积与安全)
tombstone 自带函数名默认只有地址,必须配符号表才会显示符号

6. 对应知识库文档 ​

7. 关键源码 ​

cpp
// native_crash_demo.cpp —— 故意触发 SIGSEGV(空指针解引用)
extern "C" JNIEXPORT void JNICALL
Java_com_example_NativeCrash_triggerSigsegv(JNIEnv*, jobject) {
    int* p = nullptr;
    *p = 42;            // 第 42 行:解引用空指针 → SIGSEGV
}
bash
# build.gradle 保留 unstripped so 供还原
android {
    buildTypes {
        debug { ndk { debugSymbolLevel = "FULL" } }
    }
}

接入状态 ​

✅ 已接入 Android 宿主 App:对应 NativeCrashBreakpadActivity,从 MainActivity → 「打开 Native Crash (SIGSEGV) 实验室」进入。点按钮即向自身进程发 SIGSEGV(11) 产生真实 tombstone,无需 NDK/JNI。可用 adb logcat -b crash 观察。

站点构建时间:2026/8/24 23:43:17