Android5.0L因SystemUI ANR導致的黑屏問題分析,systemuianr
一、問題現象
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,然後依附於SystemUI的statusbar和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,然後依附於SystemUI的statusbar和navigationbar以及imagewallpaper都會被阻塞,一旦SystemUI進程被Kill,這些組件都會消失,產生黑屏現象。
五、其他相關問題
第一個問題:為什麼大部分發生在FOTA升級之後?
分析:由於這個問題是發生在啟動或者重啟時,而且只有這個過程才會有很小機率觸發。而FOTA之後會自動重啟,所以就有機率觸發這個問題,由於使用者平時使用中很少重啟,所以機率不高。
Analyzed by vincent.song from SWD2 Framework team.
vincent.song@tcl.com
201505221140
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。