Android Native Crash的log分析和定位


非原創,學習於:

https://blog.csdn.net/helldevil/article/details/6682211

 

作為測試,如果能掌握log定位是一件很好的事情。

在日常工作中,有機會也會進行學習

但學習的相對於開發來說,會較為淺層。以下相關信息有做一定隱藏。

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

09-22 09:39:43.083 F/libc ( 9479): Fatal signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x7a05b46000 in tid 9714 (Thread-5), pid 9479 (m.xxxx.gallery)
09-22 09:39:43.247 F/DEBUG ( 9733): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
09-22 09:39:43.248 F/DEBUG ( 9733): Build fingerprint: 'xxxx/6025H/HONG_KONG:11/RP1A.200709.001/7KXX:user/release-keys'
09-22 09:39:43.248 F/DEBUG ( 9733): Revision: '0'
09-22 09:39:43.248 F/DEBUG ( 9733): ABI: 'arm64'
09-22 09:39:43.249 F/DEBUG ( 9733): Timestamp: 2020-09-22 09:39:43+0800
09-22 09:39:43.249 F/DEBUG ( 9733): pid: 9479, tid: 9714, name: Thread-5 >>> com.xxxx.gallery <<<
09-22 09:39:43.249 F/DEBUG ( 9733): uid: 10099
09-22 09:39:43.249 F/DEBUG ( 9733): signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x7a05b46000
09-22 09:39:43.249 F/DEBUG ( 9733): x0 0000007763d89c70 x1 0000000000000002 x2 0000007a0428b56c x3 0000007a0428db9c
09-22 09:39:43.249 F/DEBUG ( 9733): x4 0000000000000001 x5 0000000000000008 x6 0000007a0428b4e8 x7 0000000000000025
09-22 09:39:43.249 F/DEBUG ( 9733): x8 0000000000000023 x9 000000000000000a x10 0000000000000021 x11 000000000000004a
09-22 09:39:43.249 F/DEBUG ( 9733): x12 0000007a04289050 x13 0000007a05b45fe4 x14 0000007a0428db18 x15 0000000000000021
09-22 09:39:43.250 F/DEBUG ( 9733): x16 0000000000000048 x17 0000000000000001 x18 0000007a0428b680 x19 0000000000000001
09-22 09:39:43.250 F/DEBUG ( 9733): x20 0000007a0428b5e0 x21 0000007a0428dc10 x22 0000000000000009 x23 0000000000000084
09-22 09:39:43.250 F/DEBUG ( 9733): x24 000000770376bcb8 x25 000000770376bb50 x26 0000007a0428b664 x27 0000007a0428dc94
09-22 09:39:43.250 F/DEBUG ( 9733): x28 0000007a05b45f58 x29 0000007a05b45ecc
09-22 09:39:43.250 F/DEBUG ( 9733): lr 0000007a05b45e50 sp 0000007763d89650 pc 0000007762910674 pst 0000000020000000
09-22 09:39:43.500 F/DEBUG ( 9733): backtrace:
09-22 09:39:43.500 F/DEBUG ( 9733): #00 pc 00000000002eb674 /data/app/~~JBZ8-fwaJ0pWsj4hEf8wkQ==/com.xxxx.gallery-BwSA1NtaDN7WDKjYMNNIOw==/base.apk!libfacenet.so (offset 0x3552000) (BuildId: cd8fc953d21f932a219d2676a37ec6747333fb1f)
09-22 09:39:43.500 F/DEBUG ( 9733): #01 pc 00000000002e2e90 /data/app/~~JBZ8-fwaJ0pWsj4hEf8wkQ==/com.xxxx.gallery-BwSA1NtaDN7WDKjYMNNIOw==/base.apk!libfacenet.so (offset 0x3552000) (BuildId: cd8fc953d21f932a219d2676a37ec6747333fb1f)
09-22 09:39:43.500 F/DEBUG ( 9733): #02 pc 00000000002dbac4 /data/app/~~JBZ8-fwaJ0pWsj4hEf8wkQ==/com.xxxx.gallery-BwSA1NtaDN7WDKjYMNNIOw==/base.apk!libfacenet.so (offset 0x3552000) (BuildId: 

...
09-22 09:39:43.508 F/DEBUG ( 9733): #40 pc 000000000055c384 /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeVirtualOrInterfaceWithJValues<art::ArtMethod*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, jvalue const*)+460) (BuildId: 132c9fd75471ac7a6d1d7331ebfeeb49)
09-22 09:39:43.508 F/DEBUG ( 9733): #41 pc 00000000005ac204 /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallback(void*)+1308) (BuildId: 132c9fd75471ac7a6d1d7331ebfeeb49)
09-22 09:39:43.508 F/DEBUG ( 9733): #42 pc 00000000000b0658 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+64) (BuildId: b32164423ca0fcdb55f8214db90688c3)
09-22 09:39:43.508 F/DEBUG ( 9733): #43 pc 0000000000050150 /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: b32164423ca0fcdb55f8214db90688c3)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

1.怎么判斷是Native crash?

有時候是不會有提示框出現,行為可以表現為閃退。

查看log,有以下信息:

Fatal signal 11 (SIGSEGV)

可過濾DEBUG 級的log

上一張別人的圖,簡單分析log信息:

 

 

 

2.怎么進一步分析?

2.1 看橙色語句:

09-22 09:39:43.249 F/DEBUG ( 9733): pid: 9479, tid: 9714, name: Thread-5 >>> com.xxxx.gallery <<<

橙色部分是讓我們確認問題到底發生在哪個線程中,是主線程還是子線程;

這個的判斷依據是:

如果PID和TID相同,問題則在主線程

如果PID和TID不相同,那么問題則出在子線程

從上面例子看,該crash發生在子線程。

 

2.2 看backtrace下的log

就是下面這一堆。

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

09-22 09:39:43.500 F/DEBUG ( 9733): backtrace:
09-22 09:39:43.500 F/DEBUG ( 9733): #00 pc 00000000002eb674 /data/app/~~JBZ8-fwaJ0pWsj4hEf8wkQ==/com.xxxx.gallery-BwSA1NtaDN7WDKjYMNNIOw==/base.apk!libfacenet.so (offset 0x3552000) (BuildId: cd8fc953d21f932a219d2676a37ec6747333fb1f)
09-22 09:39:43.500 F/DEBUG ( 9733): #01 pc 00000000002e2e90 /data/app/~~JBZ8-fwaJ0pWsj4hEf8wkQ==/com.xxxx.gallery-BwSA1NtaDN7WDKjYMNNIOw==/base.apk!libfacenet.so (offset 0x3552000) (BuildId: cd8fc953d21f932a219d2676a37ec6747333fb1f)
09-22 09:39:43.500 F/DEBUG ( 9733): #02 pc 00000000002dbac4 /data/app/~~JBZ8-fwaJ0pWsj4hEf8wkQ==/com.xxxx.gallery-BwSA1NtaDN7WDKjYMNNIOw==/base.apk!libfacenet.so (offset 0x3552000) (BuildId: 

...
09-22 09:39:43.508 F/DEBUG ( 9733): #40 pc 000000000055c384 /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeVirtualOrInterfaceWithJValues<art::ArtMethod*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, jvalue const*)+460) (BuildId: 132c9fd75471ac7a6d1d7331ebfeeb49)
09-22 09:39:43.508 F/DEBUG ( 9733): #41 pc 00000000005ac204 /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallback(void*)+1308) (BuildId: 132c9fd75471ac7a6d1d7331ebfeeb49)
09-22 09:39:43.508 F/DEBUG ( 9733): #42 pc 00000000000b0658 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+64) (BuildId: b32164423ca0fcdb55f8214db90688c3)
09-22 09:39:43.508 F/DEBUG ( 9733): #43 pc 0000000000050150 /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: b32164423ca0fcdb55f8214db90688c3)

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

這里所顯示的程序的執行流程,實際的執行順序是#XX-->#00

所以一開始我們的目的是分析第一個出現問題的動態連接庫

 #43 pc 0000000000050150 /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: b32164423ca0fcdb55f8214db90688c3)

再一級一級往上分析,通常都是分析到自己代碼庫里面部分。

 

3.定位問題

這一部分涉及到代碼分析,因為缺少相關環境,所以這部分會以學習博客內容為主。有興趣也可以去看原博客。

 

所以一開始我們的目的是分析第一個出現問題的動態連接庫
   #15  pc 0001173c  /system/lib/libc.so

 A. 首先按圖索驥,找到你的目標,libc.so這個一般會在你編譯完的目標目錄下,也就是out/target/product/your_pro/system/lib這個目錄下。

B. 一般你如果用的是還像樣的linux系統,會有個地址解析的命令:

      addr2line(負責解析動態連接庫的)

        (如果你是悲劇,沒有這個命令,那好吧, google早就預料到會有象你這樣的悲劇人,他們在prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi-addr2line,給您准備了個,咋就用這個吧,功能一樣,沒啥區別)

     addr2line -e -f libc.so 0001173c  //紅色是你的目標庫,藍色是你出問題的地址,看看#15這行

    結果出現:

  pthread_create

        0

 

這個只是告訴你函數入口,至於具體執行到這個函數的哪個地方掛了,還得再看。

C. 找到了是哪個部分出了問題,繼續分析

   使用

    objdump -S -D libc.so > deassmble_libc.txt

        反匯編下你的動態連接庫文件,並且將它寫入一個文件中。

   打開這個反匯編過后的重定向文件,在查詢的時候輸入1173c這個偏移地址,你會看到:

  00011684 <pthread_create>:
   11684:       e92d4ff0        push    {r4, r5, r6, r7, r8, r9, sl, fp, lr}
   11688:       e24dd01c        sub     sp, sp, #28     ; 0x1c
   1168c:       e1a06001        mov     r6, r1
   11690:       e1a08002        mov     r8, r2
   11694:       e1a09003        mov     r9, r3
   11698:       e3a04001        mov     r4, #1  ; 0x1
   1169c:       e59f521c        ldr     r5, [pc, #540]  ; 118c0 <pthread_create+0x23c>
   ...

   1173c:       ebffec2b        bl      c7f0 <__pthread_clone>-->就是他了,對你成功了。

   ...

這個是ARM匯編,需要你翻譯成對應的C函數去看,這里我就不做解釋了,照着前面的步驟.(PS:估計就是步驟B?)

 

對上面中#15-->#00 一共16行慢慢去找,直到找到#00行的問題函數,其實,最后一個#00行的是最重要的(前面不找也行,但是可以多給你提供問題信息,和流程),因為他是第一目擊者,也是Crash前的第一現場。所以找到這個函數很重要.

 

 

假設我們最后經過萬里長針發現#00的出錯的地方是pXX->member掛了

那么你可以懷疑兩個地方:

1 您的指針是空指針,但是現實與理想總是十萬八千里,多數情況下很少出現,而且你分析代碼后,也會對自己說怎么可能。絕大多數情況下,從我的經驗來講,很少會有空指針這種低級錯誤,但是不排除哪個2貨出現了這么個問題。如果是這個問題,那么恭喜你,你很幸運。

2 還有就是懷疑越界和內存地址被擠占。就拿我以前的經驗,指針不是空,但是根據匯編碼看,是訪問成員變量掛了,這個地址肯定是被占用了。

  

  針對第2種比較惡心的情況,就需要你看整個log的流程了,需要你看下主要的mainlog關於出現crash前的動作,看看是哪個孫子占用的,以最近原則為先,從下往上看,唉,說句實在話,李白的一句話可以形容整個過程:"蜀道難,難於上青天啊"。工作量大,而且要細致。我也沒什么辦法。。。

 

  還有一種情況,就是內存不夠,導致了您的地址被擠占了,出現low memory, no more ...這樣的語句,以及大量出現GC_FOR_MALLOC關於GC的東西(如果是少量的,可以忽略,大量的話),呵呵表明你的某個進程在吞噬你的內存,存在內存泄漏。坑爹啊,這個問題,是最難查的,需要你花大量時間,去看內存的變化。一般看內存的情況是

cat /proc/meminfo 

 

  空閑內存=buffer+cache+free這三個字段,Active字段是已經使用的內存,Total不用說,是總的物理內存。(記住 free不高,並不代表你的內存空閑不高,海水不可斗量,需要看全了3個字段的總和才是空閑內存)

  如果你想具體跟蹤每個進程的內存使用情況,還是在/proc下面,對應了N多的數字文件,那個其實是PID號,進去后cat status可以看到

  VMRSS XXXKB就是你當前進程的使用內存量,此外還有一些其他的內存數據,包括頁等等

  里面還有很多有用的數據,如果你想跟蹤所有的進程的內存情況,推介大家可以看看linux ps命令的源碼,看看人家是怎么在/proc下遍歷進程,並且提取屬性值的。

 

寫個daemon,跟蹤一段時間,記錄下各進程內存的變化,然后就是通宵的分析。。。。

總之,這類問題,很難定位,也很難解決,需要花時間,精力去分析。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM