當前位置:
首頁 > 最新 > 騰訊大神教你用Hook技術解決因java native導致的crash

騰訊大神教你用Hook技術解決因java native導致的crash

導讀ID:TOP100case

導讀:Hook並不是什麼新技術,在PC時代就已經有很多這方面的應用;Android Hook也不算是一種新技術,在網上可以找到各種各樣Android Hook技術的帖子。但這些貼子大部分都在講注入,而非在實際項目中的運用,我們開始探索Android Hook的應用也完全是項目逼迫。本文主要內容包括為什麼要研究Android Hook、怎樣讓它在項目中發揮作用、怎樣作用於測試領域。

(全文共2681字 預計閱讀時長:3分鐘)

項目挑戰

對於一個日活躍用戶在千萬以上的Android APP來說,系統的穩定性是至關重要的,但是我們發現,APP java和native導致的crash已經是各佔一半了。對於java導致的crash我們還能通過修改自身代碼來修復,但是native導致的怎麼來修復呢?尤其是這類crash幾乎都是系統級API的問題。下面是之前相關業務中出現的實際問題:

Android中一項APP的native crash佔比高達40%-60%;

當前業務開發對於native crash嘗試了很多方法,但是效果甚微;

即使業務開發找到原因,也由於是系統問題,而難以下手;

測試&開發對於native crash的重現條件和方法也相對較少。

如何解決native crash的問題,首先是要了解這些crash產生的原因,也就是需要收集crash的信息,然後再做分析。我們現在看到無法處理的crash幾乎都是無法重現,或者重現條件非常複雜,即使是我們fix了,也無法驗證,只能發布到外網。

於是問題出現了。要解決一個crash可能就需要發布很多的版本,來不斷的查看外網是否已經修復。這樣的代價無疑是非常大的,加上若是由系統原因產生的crash,我們依舊無能為力。

基於hook的解決方案

基於上面的原因,我們設計了一套能快速驗證修復方案的解決方案,如圖1所示。

圖1 快速驗證修復方案的解決方案

由開發人員分析crash上報的堆棧信息,對照crash對應的動態庫的彙編代碼和Android源碼,找出可能出問題的地方。

嘗試著去給crash的函數添加「保護」。我們發現很多crash的原因其實都是系統函數對參數未做檢查導致的(當然也有很多是系統本身bug導致,解決方案都比較類似),所以只需要給系統函數加上「保護」,很多crash都能解決。

把修復方案文件以配置的形式下發灰度下發到客戶端,這裡採取灰度,是因為不確定這次的修復是否生效,也不知道是否會有隱藏的問題。先灰度少部分用戶手機,看是否修復。

在客戶端以hook的方式修改函數調用路徑,在調用crash的函數前先經過「保護函數」。通過上報查看下發的機器是否還有這類問題,以及是否又新增其他問題。若有則回滾配置,重新分析原因和修復方案。若無,則說明問題得到修復,修復方案成立。

這樣的解決方案優點在於允許開發人員在無需發布客戶端版本的情況下,讓外網用戶來幫助我們驗證問題是否修復,並且可以嘗試多次嘗試,直到問題修復。但這樣的方案實施需要兩個關鍵點:

crash信息上報;

客戶端的動態修復。

對於而言,大多數的APP已集成了這樣的功能,所以,我們現在討論,即如何讓客戶端在不重啟的情況下完成問題修復。這裡我們討論的都是基於Android native的問題,對於java的我們後面再討論。

對於Android native我們知道其代碼都是C/C++,這樣就可以直接使用Android hook的方式來替換運行時的函數。

可能做過Android hook技術的一些朋友會有這樣的一些疑問,直接運用這些函數到項目是否會有兼容性、性能和穩定性方面的問題。畢竟Android機型繁多,即使常見的也有幾百款,每款機型對應的操作系統還可能不同。

我們在上線這個方案前針對這幾個問題做了測試數據和評估,在現網的運行數據中也確實沒有發現類似問題,但是針對問題修復可能就不是這樣的了,因為每款操作系統的函數位置、結構體等都有些許差別,所以需要針對手機機型或者說ROM來針對性地修復。

我們也發現了一些問題的聚集性,就是某native crash一般聚集在幾款特定的機型上,而這幾款機型發生crash的堆棧也是一樣的,這也為針對ROM來修復問題提供了依據。

對於使用hook方案來給系統函數加「保護」,可能會產生這樣的疑問:系統函數在這裡掛掉也許是最好的結果,強行返回可能導致系統的其他問題。

對於系統函數來說,有很多功能要做,並不是說參數有問題時,簡單的不調用就可以了,這些問題都是實際存在的。(當然這裡還存在一類負責的修復問題--系統bug,由於每個系統bug導致的問題修復方式都不同,就不在這裡詳細討論了,具體的可以參考對應系統的Android下一個版本的修復方案)

我們這裡可以通過「策略」型方案來解決這些問題:

當參數存在問題時,我們直接返回這個系統函數可能返回的錯誤值,來讓上層調用決定如何處理,一般上層都會有一套容錯的機制。

對於不得不執行的函數,我們需要一定的變通方案,把參數設置為系統函數能識別的錯誤類型,例如:當參數為野指針時,系統函數當然不能識別,我們把參數改為空指針,系統函數就能正常處理這種錯誤,讓程序繼續按正常的方式走下去。

這樣做會給測試帶來什麼樣的好處呢?我們先看一下沒有這種方式時,我們是怎麼來做的:發現現網crash,先由測試復現,一般情況下是無法復現的,然後聯繫用戶,看用戶是否可以重現,但是聯繫用戶這個過程本身非常耗時的,一天一般最多聯繫一兩個用戶。聯繫到用戶後,用戶也不能復現,這時開發人員會嘗試修復,修復後,由於無法復現,所以測試也無法驗證是否真的修復,只能是驗證一下看看功能是否正常。整個問題修復耗時好多天,還無法確定是否修復。

現在呢:我們只需嘗試修復,由測試驗證是否有其他影響,然後就可以直接灰度下發配置,整個耗時3小時左右。

基於hook的java解決方案

前面講述了基於hook的native解決方案,對於業務代碼來說更多的是java層的,當然出問題的概率也更大。雖然我們可以通過發布新版本的方式來修復java層的錯誤,但是每次的新版本發布都有很長的流程要走,耗時很長。如果可以像我們解決native問題那樣動態解決,那麼也就可以快速修復java層的缺陷了。

關於java層的hook,網上有很多教程,大多是基於xopsed原理的hook方案,這個方案可以實現java層hook,但是要應用在APP中存在的一個比較大的問題就是性能。從性能上來說,這個方案hook後的函數耗時會增加許多,所以要在APP中使用的話,還必須解決性能問題。

我們使用的是直接替換java類函數的JCR方案(我們內部自己這樣命名的),而去掉了xposed的中間函數,這樣性能上和原函數執行耗時的差異就僅來自函數實現本身了,基本和hook方案無關。

這樣做還帶來了另一個好處。使用xposed方案hook,對於替換函數的編寫需要使用反射,和直接在svn修復問題的代碼是不一樣的,所以需要維護兩套代碼,即。一套問題修復代碼,用於快速修復客戶端問題;一套svn修復代碼,用戶下次版本發布時直接使用。

而JCR方案是直接使用svn修復代碼編譯的補丁文件,所以只需維護svn代碼即可。

這樣做帶來了效率上的提升,通過灰度發布觀察方案是否可行,然後再全量用戶,讓用戶幫助我們去發現問題,有問題快速回滾,不會對用戶造成體驗上的有損。

小結

研發節奏越來越快,場景也越來越複雜,給予測試的時間非常有限,科技的發展使眾測和灰度恰好可以讓用戶幫助我們來測試,並發現很多我們在實驗室環境無法發現的問題,但是如何眾測和灰度可以更加高效,需要我們引入一些新的技術來讓發布更加敏捷,問題修復更加敏捷。

例如基於Android hook技術下的熱補丁就能幫助我們可以更快的修復問題,而無需發布新版本,且用戶完全無感知(無需重啟應用便可修復問題)。


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 壹佰案例 的精彩文章:

魅族應用商店伺服器端架構實踐
從騰訊遊戲的成功看產品經理如何尊重用戶反饋
我們該怎麼給DevOps下個定義?
千億成交額背後,京東技術團隊的敏捷轉型模式
Thought Works的10個案例教你打造團隊文化

TAG:壹佰案例 |

您可能感興趣

HikariCP源碼分析之leakDetectionThreshold及實戰解決Spark/Scala連接池泄漏
Win7系統提示steam client not found解決方法
如何解決 「mount.nfs:Stale file handle」錯誤
kali 使用apt-get update報錯GPG error的解決辦法
Cadence Innovus助力Realtek成功開發DTV SoC解決方案
Kanye West 已解決 Saint Pablo 巡演訴訟案
小米Pro/Air筆記本重裝系統教程及開機No Bootable Devices解決方案
Realtek藉助Cadence Innovus成功開發DTV SoC解決方案
聯想、OPPO、vivo和小米分別與Qualcomm Technologies 簽署射頻前端解決方案跨年度採購諒解備忘錄
殭屍毀滅工程steam is not enabled錯誤解決方法
智能營銷計劃的解決方案Gagapay Network
解決Electra越獄顯示Error:topanga錯誤的方法!
解決SSD問題後,Windows 10似乎跟Avast Antivirus過不去
Belle&Sebastian:如何解決人類的問題?
Antycip Simulatio推出最新VR和3D沉浸式解決方案
Kaon Interactive旨在針對行業用戶推出VR/AR解決方案
歐司朗收購Fluence Bioengineering公司 打造數字化農業解決方案領導者
解決畫面撕裂問題:Microsoft 微軟 Xbox One S/X 即將支持 AMD FreeSync「防撕裂」技術
VRstudios推出VR線下電競解決方案VRcade PowerPlay
孤島驚魂5無法解鎖vehicle takedown技能解決方法