利用系統提供的崩潰日誌解Native層Bug

對Android開發者來說,尤爲是使用NDK編寫Native層代碼的開發者,在編碼過程當中一般會碰到各類各樣的問題。追蹤問題的方式有不少,除了在代碼中添加日誌,來觀察程序運行過程當中產生的異常外,對崩潰後產生的日誌進行分析也是一種重要的定位問題的方式。html

 

Android系統自帶一個很是實用的Native層代碼崩潰監測進程debuggerd。該進程能夠監聽到應用程序的崩潰,並將崩潰後的信息輸出到文件中,供開發人員調試分析。在開發過程當中,咱們能夠經過logcat來查看debuggerd爲咱們生成的應用程序崩潰日誌。java

 

接下來,就跟你們來探討一下如何利用debuggerd爲咱們生成的應用程序崩潰日誌來定位並解決程序中存在的問題。安全

 

首先經過這個例子來介紹如何使用系統提供的崩潰日誌。代碼如圖1所示。服務器

 

圖1  代碼示例網絡

 

能夠看到,JNI_OnLoad函數中除了作一些常規性的操做之外,有這樣兩行特殊的代碼:eclipse

[代碼]java代碼:

?函數

12 int *p = 0;*p = 1;

p」是個int*類型的空指針,然後面的這個賦值操做是向這個空指針的位置寫入1。毫無疑問,這個典型的空指針賦值操做會形成應用程序直接崩潰。工具

 

將以上代碼編譯成SO文件,並運行APP。發現程序產生了崩潰,經過logcat就能夠看到如圖2所示的崩潰日誌:學習

 

圖2  系統生成的崩潰日誌測試

 

從這一段崩潰日誌中,咱們能夠看到:

 

(1)崩潰手機的Build fingerprint是:

'Huawei/H30-T00/hwH30-T00:4.4.2/HuaweiH30-T00/C00B246SP02:user/ota-rel-keys,release-keys'。

 

(2)崩潰發生的進程進程號pid爲14077,線程號tid爲14077,進程名稱爲com.example.nativecrash。

(3)signal告訴咱們:崩潰信號爲SIGSEGV,當進程中執行了一個無效的內存引用時會觸發這個類型的崩潰信號。fault addr表明發生崩潰的地址爲0,這與代碼中的空指針賦值相吻合。

 

(4)signal下面的4行信息其實就是進程崩潰時全部寄存器的一個快照。

 

(5)最後是backtrace,這部分對於定位產生崩潰的緣由是很是重要的,它反應了進程崩潰時的函數調用棧,經過它,就能夠知道在哪裏觸發了代碼崩潰,稍後會詳細分析一下這個部分。

 

簡單地解析了崩潰日誌中的信息以後,咱們就來看看怎麼定位崩潰產生的位置?從上面的分析能夠知道backtrace是接下來的分析重點。

圖3  backtrace中函數調用過程

 

如圖3所示,backtrace其實就是一個函數調用棧。最上面一行是崩潰發生的地方。從第一行能夠看出:崩潰發生在本身so中的JNI_OnLoad函數裏面,崩潰點是在so的偏移爲0x47d2的地方(須要注意的是這個偏移是指二進制文件中的偏移,並不是源碼中的偏移)。

 

那麼JNI_OnLoad函數是由誰調用的呢?從第二行就能夠知道是系統的libdvm.so中的dvmLoadNativeCode這個函數調用了該so中的JNI_OnLoad函數。綜上能夠看出,backtrace中的函數調用關係實際上是由下而上,如圖3中的箭頭所示。

 

雖然已經定位崩潰發生在so的JNI_OnLoad函數中,可是依然不知道具體發生在源碼文件的哪一行。爲了可以定位到崩潰發生在源碼文件的哪一行,故須要利用Android提供的工具:addr2line。利用該工具能夠將backtrace中顯示的崩潰點與源碼聯繫起來,這樣就能還原崩潰在源碼中的位置。具體的還原步驟以下:

 

(1)取obj目錄下的libtest.so

咱們知道,在利用ndk-build編譯so的時候會在jni的同級目錄下產生libs、obj兩個目錄,如圖4所示:

圖4  libs、obj目錄

這兩個目錄下面各有一個so,可是爲何要取obj目錄的,而不取libs目錄裏面的呢?這是由於ndk-build在生成so的時候,會生成兩份,一份是包含調試信息的so,放在obj目錄下面;一份是不包含調試信息的so,放在libs目錄下面。爲了利用addr2line工具還原崩潰點在源碼中的位置,咱們必須使用包含調試信息的so,因此須要obj目錄中的so。

 

(2)在cmd中運行下面的命令

[代碼]java代碼:

?

1 addr2line  -f  -e  libtest.so  0x47d2

其中,0x47d2就是咱們以前所看到的崩潰點。

 

運行完能夠看到如圖5所示的結果:

圖5  addr2line運行結果

從以上結果中能夠看到:崩潰發生在JNI_OnLoad函數中,崩潰點對應的源碼位置在test.cpp的第17行。那麼結果然的是在17行嗎,咱們能夠驗證一下:

 

圖6  C源碼中的崩潰點

如圖6所示,空指針賦值的操做正好就是在第17行,正是這個操做致使了崩潰。

 

至此,咱們就基本知道了如何利用系統提供的崩潰日誌來定位和解決Native層代碼的崩潰了。可是實際的狀況比咱們想象要複雜得多。以上方式只適用於開發者在調試或測試階段來獲取崩潰日誌,但當開發者將APP分發出去以後,APP運行在用戶手機上時發生了崩潰,開發者是看不到日誌的。因此一般開發者經過本身搭建崩潰日誌服務平臺,或集成第三方SDK的形式獲取應用崩潰信息。每種方式各有利弊,今天介紹一個免SDK集成的工具——360加固保

360加固保推出了「崩潰日誌」功能主要特色有:

 

(1)免SDK集成

目前有很多第三方Crash Report SDK,開發者須要在本身的apk源碼中集成SDK,那麼做爲一個開發者,他的開發成本就相應的增長了不少:

首先,開發者必須學會如何使用SDK,閱讀SDK文檔,瞭解其中的API接口,以後才能調用SDK中的API。除此以外,開發者必須得在Android Studio或者eclipse等IDE中配置好SDK的一些使用參數等,可是,這有時並非一件簡單的事,須要必定開發成本。

 

再次,因爲SDK自己也會存在一些問題(好比Bug,須要優化等),因此必然須要升級更新,那麼開發者爲了可以使用更優質的服務,就必須緊跟SDK的版本升級,不斷在本身的源碼中更改SDK,這實際上是比較麻煩的事。

 

爲了免去開發者的開發成本,360加固保推出免SDK應用崩潰日誌分析服務。無需任何開發過程,只需上傳APP進行應用加固,2分鐘左右,便可掌握最全面的應用崩潰信息。同時,APP具有了防反編譯、防破解的能力,輕鬆提高APP安全性。

 

(2)提供Native層崩潰日誌收集功能,且兼容性強

因爲Native層崩潰日誌收集的功能涉及Android系統較低層的一些系統機制,其內容較複雜,實現難度較大。因此目前市場上可以提供針對Native層的崩潰收集功能的廠商並很少。即便可以提供Native層的崩潰日誌收集,在兼容性方面也存在各類問題。

 

360加固保本身實現了一套收集崩潰日誌的接口,並不依賴系統自己提供的崩潰日誌相關接口。這樣,即使某款手機上的Android系統是基於手機廠商特殊定製的,不提供崩潰日誌相關接口,360加固保也能正常收集到此款手機上面的崩潰信息。

 

(3)Native層收集的崩潰數據更加全面

與其餘第三方應用崩潰信息廠商相比,360加固保收集的Native層崩潰日誌數據更全面,更方便開發者根據這些崩潰信息進行Bug追蹤和修復。360加固保收集的崩潰日誌信息見圖7至圖11。

 

圖8  加固保收集的應用崩潰信息

 

圖8  加固保收集的應用崩潰信息

 

圖9  加固保收集的應用崩潰信息

 

圖10  加固保收集的應用崩潰信息

 

圖11  360加固保收集的應用崩潰信息

 

(4)Native層崩潰日誌模擬Android系統收集的崩潰日誌,開發者閱讀時更方便

Android系統自己自帶崩潰日誌收集功能,圖12至圖14是Android系統爲崩潰進程收集的崩潰日誌詳情:

圖12  Android系統收集的崩潰日誌詳情

 

圖13  Android系統收集的崩潰日誌詳情

 

 

圖14  Android系統收集的崩潰日誌詳情

經過與360加固保收集到的崩潰信息對比,能夠發現,360加固保提供的崩潰日誌詳情和Android系統收集的基本沒有區別,甚至比某些手機系統上面收集的崩潰日誌還要詳細。因爲開發者在平時調試Native層代碼時,習慣看到的是Android系統打出來的Log,因此若是與Android系統收集上來崩潰日誌詳情的類似,能夠說開發者看上去會很是親切,免去開發者從新學習如何查看的煩惱。

 

(5)所須要獲取的apk權限最少

由於收集到的應用崩潰日誌須要上傳至服務器,因此APP必須有一些網絡相關權限。圖15是360加固保所需獲取的apk權限,只有三個。更少的權限對用戶來說,就意味着少了不少的安全風險;對於開發者來說,也沒必要由於收集崩潰信息而添加過多的apk自己並不使用的權限。

 

圖14   360加固保所需獲取的apk權限

 

(6)Native層支持多進程的崩潰日誌收集

360加固保提供的崩潰日誌分析服務,不管是Android中動態連接庫so中fork出來的進程,仍是Service組件的進程,凡是Native層出現了崩潰,都會被Native層崩潰信息收集功能察覺,並生成相應的崩潰信息。

原文連接:http://www.apkbus.com/blog-705730-62583.html

做者:白衣染霜花 連接:http://www.imooc.com/article/247064 來源:慕課網

相關文章
相關標籤/搜索