Tombstone 定位电量 SOC Native 崩溃复盘

结论先行

这次崩溃定位到“电量 SOC 计算对应的 native C/C++ 路径”,依据不是单点日志,而是三段证据闭环:

  1. tombstone 明确是 DartWorker 线程的 SIGSEGV 空指针崩溃。
  2. 崩溃前稳定高频出现“读电量 + Calculated battery SOC”日志。
  3. 代码中这条链路唯一跨 native 的入口是 BattCalBindings -> libbatt_cal_export.so

关键证据链

1) tombstone 直接证据

文件:tombstone_01

  • tombstone_01:6
    • name: DartWorker >>> **** <<<
    • 说明崩在 Flutter worker 线程,不是主线程 Java UI 崩溃。
  • tombstone_01:8
    • signal 11 (SIGSEGV), ... fault addr 0x1c
    • 典型 native 非法内存访问。
  • tombstone_01:9
    • Cause: null pointer dereference
    • 系统直接给出空指针解引用。
  • tombstone_01:16
    • #00 pc ... /system/app/Ruminate/Ruminate.apk
    • PC 在应用 native 代码区。
  • tombstone_01:233
    • Fault address falls at 0000001c before any mapped regions
    • 再次印证 null pointer + offset 访问模式。

2) 崩溃前业务日志证据

文件:咀嚼肌崩溃日志.txt

崩溃前反复出现:

connect   readBatteryCapacity ...
connect   readBatteryCapacity  batteryLevel ...
Calculated battery SOC: ...

这说明现场最活跃路径就是“电量读取 + SOC 计算”。

3) 代码调用链证据

文件:home.dart

文件:batt_cal_bindings.dart

结论:SOC 路径明确跨 FFI 进 native so,和 tombstone 的线程/信号模型吻合。

为什么不是其它模块

可以较高置信排除:

  1. Java/Kotlin 崩溃:应出现 FATAL EXCEPTION Java 栈,不会是 tombstone 的 SIGSEGV 形态。
  2. 纯 Dart 业务异常:通常是 Dart stack,不会表现为 native signal 11。
  3. UI 渲染主链路:常见线程是 main/RenderThread,而本次是 DartWorker

以后排查同类问题的标准流程

  1. 先分类型:FATAL EXCEPTION / ANR / Fatal signal
  2. 锁线程:pid/tid/thread name(这一步很关键)。
  3. 看信号和 fault addr:判断空指针、野指针还是主动 abort。
  4. 看 PC/LR 模块归属:系统库、第三方 so、还是应用 apk/so。
  5. 拉平崩溃前 5~30 秒业务日志:找“持续高频动作”而非“最后一行”。
  6. 反查代码调用链:定位 JNI/FFI/MethodChannel 跨边界点。
  7. 做最小化屏蔽验证:只关掉怀疑入口,观察崩溃是否消失。
  8. 条件允许时做符号化:addr2line/ndk-stack 精确到函数和行号。

本次定位结论

这是“高置信度定位到电量 SOC native 路径”的案例。

需要特别说明的边界是:当前 tombstone 没有直接还原出 libbatt_cal_export.so 的函数名,因此最终表述应为:

  • 已定位到电量 SOC 计算相关 native 路径;
  • 若要做到函数级铁证,需要补对应版本未 strip 符号做地址还原。