这是一个偶现的 crash。
某次版本更新后,本地平板、手机测试均正常,车机上运行也正常,但是后续实车偶现 crash 的问题上报,后来测试的稳定性测试中复现了 crash 问题,并提供了日志。

分析日志

image.png

拿到日志,查看 crash 堆栈,发现调用路径是从 libil2cpp.so 到 libunity.so 的。
看来这次的问题比较好找 —— 大部分调用路径都是 libil2cpp.so 中的业务逻辑。

还原 libunity.so 中的符号

虽然业务库中的信息更多,但是最终 crash 点位还是在 libunity.so 中,所以先看这里的问题。
libunity.so 的符号可以在 unity 导出 Android Library 项目时勾选导出符号信息生成,然后用 ndk 的 addr2line 工具还原堆栈地址的符号:

image.png

可以看到,是 JNI 在创建一个新的全局引用时 crash 的。 这个是 unity 引擎内部的逻辑了,作为业务开发层自然是一脸懵逼。

拿 unity NewGlobalRef google 搜索一下,发现了这个官方论坛的帖子: https://forum.unity.com/threads/fatal-exception-at-unityengine-androidjni-newglobalref.1178776/

里边有人提到:“I found what was causing the crash, you cannot create a AndroidJavaObject outside the Unity MainThread.”。

还原 libil2cpp 的符号

接下来分析是什么调用路径导致的 crash。
libil2cpp.so 的符号可以在 build aar 库的项目根目录下的 symbols 目录下找到。

image.png

看到这里,问题就比较清晰了, 是在线程中加载缓存数据时,触发了动画开启回调通知,此时会通过 JNI 通知给 Android,和官方论坛中的说法一致。

修改此逻辑,问题修复。

☞ 参与评论