====
userspace的systemService中的Inputsystem一直監控kernelspace的InputEvent,將其進一步處理後變成上層app的InputEvent,APP對相關事件進行處理後,請求更新相關的邏輯界面,而這個則有SystemServer中的wms來負責。相關的邏輯界面更新後,則會請求Surfaceflinger來產生FrameBuffer數據,surfaceFilinger則會利用Gpu等來計算生成,displaySystem/driver則會將FrameBuffer中的數據來更新顯示出來,這樣用戶才能感知到他的動作。
死機原因==============
1軟件
邏輯異常 包括 邏輯判斷錯誤 和邏輯設計錯誤
邏輯卡頓 包括死循環 和死鎖
(1). Input Driver
* 無法接收HW 的中ISR,產生原始的InputEvent, 或者產生的InputEvent 異常.
* 無法監聽Kernel 傳遞上來的原始InputEvent, 或者轉換與傳遞異常.
* 無法正常響應Input System 傳遞過來的InputEvent, 或者響應出錯.
* WMS/SF 無法正確的對Z-Window 進行疊加轉換
* 無法更新Framebuffer 數據,或者填充的數據錯誤
* 無法將Framebuffer 數據顯示在LCM 上
對應硬件HW hang, 經常見得的情況有:
* Power
* Clock
* Memory & Memory Controller
* Fail IC
==================死機數據分析===========
死機數據 包括空間數據和時間數據
空間數據,即當時現場環境,如有哪些process 在運行,CPU 的執行情況,memory 的利用情況,以及具體的process 的memory 數據等。 時間數據,即行爲上的連續數據,比如某個Process 在一段時間內執行了哪些操作,某段時間內CPU 利用率的變化等。通常時空都是交融的,對應我們抓取資訊時往往也是。
Debug/LOG
方面,原則上user 版本只能抓到有限的資訊,eng 可以抓到更多的資訊,Debug 能力更強,推崇使用eng 版本開發測試
*
在eng 版本上,LOG 量 >= user 版本的log 量,一些地方會直接check eng/user 版本來確認是否打印LOG
* user 版本默認關閉uart, eng 版本默認開啓uart
* 在eng 版本上,開啓ANR 的predump, 會抓取ftrace,可以得到更多ANR的資訊
* 在eng 版本上,可用rtt 抓取backtrace,可開啓kdb 進行kernel debug, 可用ftrace 抓取cpu 執行場景
* MTK aee 在ENG 版本抓取更多的異常資訊,比如native exception 會抓取core dump 信息 (2) 性能方面,原則上進行性能測試請使用user 版本測試
* user 版本爲提高第一次開機速度,使用了DVM 的預優化,將dex 文件分解成可直接load 運行的odex 文件,ENG 版本不會開啓這項優化
* 更少的LOG 打印,uart 的關閉,原則上user 版本的性能要優於eng 版本 (3) 如何確認user/eng 版本
* Java 層,check
android.os.Build 類中的TYPE 值
* native 層,property_get(ro.build.type, char* value, eng); 然後check value 值
* Debug 時, adb shell getprop ro.build.type 返回值如果是user 即user 版本,eng 即eng 版本
* Log 確認, mobile log/Aplog_xxxxx/versions 中查看ro.build.type 屬性 (4) 如何編譯user/eng 版本
* 默認編譯是eng 版本,如果需要編譯user 版本,請加入參數 -o=TARGET_BUILD_VARIANT=user 如:
./mk -o=TARGET_BUILD_VARIANT=user mt6577_phone new
其關鍵是分析Java
Heap
*
抓取Hprof 的手法,如:
第一種方式: 使用am 命令
第二種方式:
使用DDMS 命令
第三種方式: 通過代碼的方式
在android.os.Debug
這個class 中有定義相關的抓取hprof 的method.
如: public static void dumpHprofData(String fileName) throws IOException;
這樣即可在代碼中直接將這個process 的hprof 保存到相對應的文件中,注意這個只能抓取當時的process.
如果想抓其他的process 的hprof, 那麼就必須通過AMS 幫忙了。
可以先獲取IActivityManager 接口,然後調用它的dumpheap 方法。具體的代碼,大家可以參考
frameworks/base/cmds/am/src/com/android/commands/am/am.java 中的調用代碼