天天看點

mPaaS最佳實踐之《Android Native crash處理》

一 背景

目前

mPaas

Android是使用的是Crash SDK對閃退進行的處理,CrashSDK 是 Android 平台上一款功能強大的崩潰日志收集 SDK,有着極高的崩潰收集率和完整、全面的崩潰日志資訊,生成的日志内容非常利于問題的跟進和解決。在我們的日常運維中,經常遇到一些閃退,無法直接從閃退堆棧看到原因,尤其是一些非Java的Native的閃退,這裡分享下在mPaas架構下怎麼使用Crash SDK對閃退進行分析。

二 閃退封包分析工具介紹

對于mPaas的使用者,從MAS上閃退分析平台導出的一般是原始的閃退資訊,閃退資訊比較多,如果直接閱讀會比較困難,使用者可以通過下載下傳Chrome的插件

LogAnalyzer

,LogAnalyzer會将Crash SDK生成的日志文本内容轉化成可視效果較強的 HTML 頁面展現,功能還是很強大的,主要包含:

1. 高亮顯示日志中重點資訊,并使用不同顔色區分;

2. 支援日志内容整體結構預覽,快速定位重點内容;

3. 常見崩潰原因提醒;

安裝好chrome插件後,還需要做以下配置

1. 修改閃退檔案字尾為 .txt

由于MAS上預設下載下傳的檔案字尾是.dat,需要改為.txt,否則 LogAnalyzer 會不識别

2. 修改插件配置

由于 Chrome 預設權限限制,任何 Chrome 插件預設都不能通路檔案網址,需要在 Chrome 插件中進行如下操作。

  1. 打開 Chrome 插件管理頁面 chrome://extensions/
  2. 找到 LogAnalyzer 插件,點選 “詳細資訊" 進入設定:
mPaaS最佳實踐之《Android Native crash處理》
  1. 找到允許通路檔案網址選項,并勾選:
  2. 打開或者重新整理日志頁面,LogAnalyzer 就生效了。

3. 生效效果

把日志檔案直接拖到chrome後,可以看到右邊插件生效後,可以通過不同顔色顯示閃退資訊的各個字段

首次打開後的使用說明如下:

mPaaS最佳實踐之《Android Native crash處理》

正常檢視閃退截圖如下:

mPaaS最佳實踐之《Android Native crash處理》

三 閃退分析舉例

我們經常在日常運維中遇到一些非Java的Native子產品閃退,比如UC。這種時候很多時候隻能去聯系UC團隊進行支撐,其實很多場景下,閃退的根因并不是UC,隻是最後的閃退點在UC。以我最近日常運維中比較常遇到的UC核心的閃退為例,對一些案例的處理分享如下。

1. java空指針導緻UC閃退

我們在閃退點上可以看到以下閃退(已經隐藏客戶apk相關資訊),如果隻是從這看我們暫時沒有任何線索,我們繼續往下看日志

mPaaS最佳實踐之《Android Native crash處理》

當看到logcat節點資訊的時候,我們發現了線索,首先我們看到關鍵字:begin to generate native report, 表示目前是閃退日志上報的日志,我們在往前看,logcat節點裡列印了異常堆棧資訊,從堆棧資訊可以看到,是由于precreate操作觸發了底層的空指針,進而導緻初始化異常,最後觸發了閃退。解決方案就是臨時關閉預建立,進而規避了閃退。

mPaaS最佳實踐之《Android Native crash處理》

從上面的案例我們可以看出,

  1. Native的閃退不一定是Native子產品的原因導緻的,有可能是由于java導緻的異常,進而導緻Native閃退
  2. begin to generate native report 附近可以看閃退相關的logcat資訊,協助定位閃退的一些上下文日志。

2. 上層OOM導緻UC閃退

首先我們看上報的閃退點的日志如下圖所示,閃退在了RenderThread裡,也是毫無頭緒。

mPaaS最佳實踐之《Android Native crash處理》

我們繼續硬着頭皮往下看,在logcat節點裡查找begin to generate native report上報節點,我們看到了大量的底層OOM的異常日志,基本大機率确定是OOM的原因了。剩下的就是查找OOM是哪裡觸發的。

mPaaS最佳實踐之《Android Native crash處理》

點選閃退裡的記憶體節點,基本原因就比較清晰了,目前手機的vmsize基本已經到最大了,我們知道對于 32 位的程序,APP 可使用的 VmSize 最大為 3GB,不過當運作在 64 位 CPU 上時,VmSize 最大可超過 3GB,接近 4GB。但是由于核心需要占據一部分,以及不同的ROM版本的差别,我們發現有以下規律:android  8.1.0 及之後的系統,大部分 native oom crash 發生時 vmSize 分布在 3.5 - 3.9 G 的位置,相對較為集中。是以下面的案例的解決思路就變成了怎麼解決OOM了。

mPaaS最佳實踐之《Android Native crash處理》

3. FD誤關導緻UC閃退

上報的日志如下圖所示,我們大概隻能看出SIGILL有可能是主動崩潰,崩潰ILL_ILLOPC表示非法操作。

mPaaS最佳實踐之《Android Native crash處理》

然後我們繼續看logcat節點的begin to generate native report, 基本确認原因是因為uc使用的FD對象被其他程式關閉。

mPaaS最佳實踐之《Android Native crash處理》

随後UC提供了帶FDscan的工具包,通過我們複現後發現,是由于UC調用shouldIntercept回調的輸入流對象被其他子產品close掉了,導緻UC使用的時候發現FD對象已經被關閉,進而做了崩潰處理。最後的處理方案就變成了使用者解決其他子產品的誤關FD的問題。

mPaaS最佳實踐之《Android Native crash處理》

四 總結

綜合以上的case分析,在遇到Native子產品閃退的時候,一般如果從直接的閃退堆棧看不出原因的時候,不要心急,可以搜尋begin to generate native report 找到崩潰上下文,多看看logcat閃退上下文的日志,會有一些收獲,同時對于oom類型的問題,可以結合目前記憶體統計來看。