这是一个偶现的 crash。
某次版本更新后,本地平板、手机测试均正常,车机上运行也正常,但是后续实车偶现 crash 的问题上报,后来测试的稳定性测试中复现了 crash 问题,并提供了日志。
分析日志
拿到日志,查看 crash 堆栈,发现调用路径是从 libil2cpp.so 到 libunity.so 的。
看来这次的问题比较好找 —— 大部分调用路径都是 libil2cpp.so 中的业务逻辑。
还原 libunity.so 中的符号
虽然业务库中的信息更多,但是最终 crash 点位还是在 libunity.so 中,所以先看这里的问题。
libunity.so 的符号可以在 unity 导出 Android Library 项目时勾选导出符号信息生成,然后用 ndk 的 addr2line 工具还原堆栈地址的符号:
可以看到,是 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 目录下找到。
看到这里,问题就比较清晰了, 是在线程中加载缓存数据时,触发了动画开启回调通知,此时会通过 JNI 通知给 Android,和官方论坛中的说法一致。
修改此逻辑,问题修复。
本文链接:https://www.zoucz.com/blog/2023/03/23/93292fb0-c950-11ed-9fa0-5dbc93f9d3ee/