非原創,學習於:
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,跟蹤一段時間,記錄下各進程內存的變化,然后就是通宵的分析。。。。
總之,這類問題,很難定位,也很難解決,需要花時間,精力去分析。
