Android5.0L因SystemUI ANR导致的黑屏问题分析

简介: 一、问题现象1、用户直观看到的现象是黑屏。2、出问题时StatusBar、NavigationBar和墙纸消失。3、大部分发生在FOTA重启之后,出现概率很低。


一、问题现象

1、用户直观看到的现象是黑屏。

2、出问题时StatusBar、NavigationBar和墙纸消失。

3、大部分发生在FOTA重启之后,出现概率很低。


Platform:MSM8916

Android版本:5.0.2L

BuildType:user

系统软件版本:VA6V+L5V0

系统RAM:1GB


参考机行为:

1、5.0L的Nexus4和5.1L的Nexus5都没有重现此问题


二、解决方案

通过初步分析、深入分析(具体分析过程、关键代码log下面会附上)我们清楚的知道了问题发生的原因:

1、开机初始化的过程中需要获取camera的相关参数,获取的过程中会以api级别打开camera(用户不可见的形式打开)然后快速关闭

2、在打开的过程中会开启一个Thermal deamon 线程进行thermal相关的处理,然后关闭时会等待这个thermal deamon线程退出

3、这个线程开启的时候会通过异步的方式执行一次thermal相关的处理,并等待结果返回, 执行的方式是多线程异步处理

在当前代码的执行状态下有一定概率(很小,只有开机或者重启时走这个流程)出现因为调度原因而先执行了closecamera的操作并先删除了异步处理结果的链表,然后等待thermal  deamon线程退出,从而导致thermal deamon被唤醒时异步处理结果的链表已经被删除而出现死结。一旦死结产生,SystemUI就会ANR,然后依附于SystemUIstatusbar和navigationbar以及imagewallpaper都会阻塞,一旦SystemUI进程Kill,这些组件都会消失,产生黑屏现象。


针对以上问题的根本原因,我们给出以下解决方案:

1、修正代码处理顺序

Closecamera时先执行m_thermalAdapter.deinit等待thermal deamon线程将结果处理完成退出并返回,再free all pending api results,因为m_thermalAdapter.deinit会依赖pending api results,这同样是遵循初始化和反初始化的栈原则,即opencamera时最后初始化的是依赖别人最多的,但是不被别人依赖,因此closecamera时需要先反初始化在opencamera时最后初始化的,按照栈的方式原则处理。

2、方案相关的具体代码和log

以上是发生死锁时锁对应的log以及相应代码和调用栈,通过红线圈住部分我们可以看到发生问题时的关键调用关系和状态,同时也给出了代码处理顺序有问题的地方。

3、最终方案的代码修改


三、问题初步分析

以Idol347出问题时候的一份典型trace和log为例,发现出问题时SystemUI的主线程block在了一个向CameraService发起的Binder调用中,从而导致SystemUI

的后续事件TimeOut引起ANR,主线程的具体trace如下:

然后继续追踪CameraService的服务端的trace,发现/system/bin/mediaserver中的处理CameraService的Binder线程也被block了,然后追踪trace中各个线程的调用栈和互斥锁的使用,发现处理调用CameraService的addlistener的Binderthread之所以被阻塞,是因为另外一个binder thread先占用了锁,然后在占用的过程中去注册thermal回调,但是注册的过程需要占用另外一个锁,但是这个锁被第三个thread在注销thermal回调的时候先占用,并且join另外一个thread,因此整个依赖环需要另外一个thread退出才能解,从当前的问题现象来看,这个thread不会太快退出,所以导致了ANR和黑屏问题。

通过初步分析我们发现的问题:

是否需要占用着锁的情况下去join另外一个thread,或者这种状态是否合理?

具体的调用栈和代码中锁的关系如下:

四、深入分析问题

经过初步我们定位到了第一个问题点,同时也产生了1个问题,接下来我们继续深入分析以期能到找到答案和问题的根本原因。

1、是否需要占用着锁的情况下去join另外一个thread,或者这种状态是否合理?

通过进一步分析和查看代码发现,Join的另外一个thread不能很快退出是因为它在执行callback时等待另外一个条件的满足,具体逻辑调用关系如下:

另外一个条件之所以不满足的原因:

开机初始化的过程中需要获取camera的相关参数,获取的过程中会以api级别打开camera(用户不可见的形式打开)然后快速关闭,在打开的过程中会开启一个Thermal deamon 线程进行thermal相关的处理,然后关闭时会等待这个thermal deamon线程退出,但是这个线程开启的时候会通过异步的方式执行一次thermal相关的处理,并等待结果返回,由于是多线程的异步处理,在当前代码的执行状态下就有一定概率(很小)出现因为调度原因而先执行了closecamera的操作并先删除了异步处理结果的链表,然后等待thermal  deamon线程退出,从而导致thermal deamon被唤醒时异步处理结果的链表已经被删除而出现死结。

一旦死结产生,SystemUI就会ANR,然后依附于SystemUIstatusbar和navigationbar以及imagewallpaper都会阻塞,一旦SystemUI进程Kill,这些组件都会消失,产生黑屏现象。

五、其他相关问题

第一个问题:为什么大部分发生FOTA升级之后?

分析:由于这个问题是发生在启动或者重启时,而且只有这过程才会很小概率触发。而FOTA之后自动重启,所以有概率触发这个问题,由于用户平时使用中很少重启,所以概率不高


Analyzed by vincent.song from SWD2 Framework team.

vincent.song@tcl.com

201505221140


目录
相关文章
|
7月前
|
安全 Android开发
Android 预置可卸载分区接收不到任何广播问题分析和解决
Android 预置可卸载分区接收不到任何广播问题分析和解决
225 0
|
数据库 Android开发
android 如何调查并解决 ANR
android 如何调查并解决 ANR
74 0
|
1月前
|
缓存 Java 数据库
Android的ANR原理
【10月更文挑战第18天】了解 ANR 的原理对于开发高质量的 Android 应用至关重要。通过合理的设计和优化,可以有效避免 ANR 的发生,提升应用的性能和用户体验。
124 56
|
5月前
|
算法 Java API
Android性能优化面试题经典之ANR的分析和优化
Android ANR发生于应用无法在限定时间内响应用户输入或完成操作。主要条件包括:输入超时(5秒)、广播超时(前台10秒/后台60秒)、服务超时及ContentProvider超时。常见原因有网络、数据库、文件操作、计算任务、UI渲染、锁等待、ContentProvider和BroadcastReceiver的不当使用。分析ANR可借助logcat和traces.txt。主线程执行生命周期回调、Service、BroadcastReceiver等,避免主线程耗时操作
73 3
|
5月前
|
缓存 安全 Java
Android深入Binder拦截问题分析
【7月更文挑战第1天】Android Binder 拦截可实现虚拟化、测试、SDK检测、逆向分析及ROM扩展。通过Java层aidl代理,利用IBinder接口规范来拦截通信。拦截步骤包括:替换Binder服务缓存对象,如ActivityManagerService;代理ServiceManager以控制服务获取。此操作需系统权限,可能涉及安全风险和版本差异,非必要时应谨慎。
|
7月前
|
XML 存储 测试技术
Android系统 添加动态控制SystemUI状态栏、导航栏和下拉菜单
Android系统 添加动态控制SystemUI状态栏、导航栏和下拉菜单
1307 1
|
7月前
|
XML Android开发 数据格式
android 9 Systemui 动态隐藏导航栏
android 9 Systemui 动态隐藏导航栏
231 0
|
7月前
|
调度 Android开发
Android9底部导航栏出现空白按钮问题分析
Android9底部导航栏出现空白按钮问题分析
49 0
|
7月前
|
Android开发
Android SystemUI去掉拖动亮度条QSPanel界面隐藏功能
Android SystemUI去掉拖动亮度条QSPanel界面隐藏功能
157 0
|
7月前
|
缓存 Java 数据库
Android 性能优化: 请解释ANR(Application Not Responding)是什么,如何避免它?
Android 性能优化: 请解释ANR(Application Not Responding)是什么,如何避免它?
117 0