02-应用冻屏
本文件汇总该版本中归类为应用冻屏的历史修复,重点包括死锁、锁重入、跨线程阻塞和可能导致应用无响应的等待链路问题。
1. getTurboModule 持锁创建 TM 导致死锁并引发卡死
- 修改日期:2024-10-23
- 版本:0.77.18
- 问题描述:
TurboModuleProvider::getTurboModule()在持有m_cacheMtx时同步执行m_createTurboModule(...),多线程或重入场景下如果创建链路再次请求 TurboModule,可能因缓存锁重入而死锁,最终表现为卡死或被系统判定为闪退。 - 影响模块:TurboModuleProvider / TurboModule
- 问题类型:Deadlock / Freeze
- 提交 / PR:7420d467f
- 详细内容:修复把
getTurboModule()的持锁范围拆成两段:先加锁读取缓存,命中后立即返回;未命中时先释放m_cacheMtx,在无锁状态下执行m_createTurboModule(...)创建模块,创建成功后再重新加锁写回m_cache。这样就避免了在持有缓存锁的同时进入 TM 创建链路,消除了创建过程中再次请求 TurboModule 时的锁重入死锁。
2. 主线程销毁 RNInstance 触发死锁检测并导致崩溃
- 修改日期:2025-07-25
- 版本:0.77.18
- 问题描述:主线程持有 RNInstance 的最后一个引用并触发销毁时,TurboModuleProvider 等路径仍可能重新锁住实例,触发 deadlock detection 并导致崩溃。
- 影响模块:RNInstance / TurboModuleProvider / TurboModuleFactory
- 问题类型:Deadlock Crash
- 提交 / PR:d113ce259 / !1297
- 详细内容:修复为 RNInstance 引入带销毁状态判断的
SafeWeak和m_isAboutToBeDestroyed标记,在onDestroyRNInstance()中先标记实例即将销毁,再把TurboModuleProvider、TurboModuleFactory等模块中保存的实例弱引用升级为SafeWeak,阻断非 JS 线程在销毁阶段重新锁住 RNInstance。
3. FontRegistry 锁顺序不一致导致死锁
- 修改日期:2026-01-07
- 版本:0.77.44
- 问题描述:JS 线程与 UI 线程对
FontRegistry内两把锁采用了相反的加锁顺序,导致双向等待并形成死锁。 - 影响模块:FontRegistry
- 问题类型:Deadlock
- 提交 / PR:278db7406 / !1984
- 详细内容:提交把原先分散的两次加锁改成一次
std::scoped_lock原子加锁,根治锁顺序不一致问题。该问题虽然标题不是 crash,但提交体带有明确 native 堆栈,属于典型稳定性问题。