android so庫導致的閃退及tombstone分析

android中有3種crash情況:未捕獲的異常茄唐、ANR和閃退孝扛。未捕獲的異常一般用crash文件就可以記錄異常信息,而ANR無響應表現就是界面卡著無法響應用戶操作乎芳,而閃退則是整個app瞬間退出遵蚜,個人感覺對用戶造成的體驗最差帖池。閃退一般是由于調用so庫出錯導致,像類似非法地址訪問等吭净。

閃退發(fā)生時在logcat中將日志過濾條件選為“No Filters”就可以看到完整的閃退日志睡汹,或者叫tombstone(墓碑)文件。
tombstone(墓碑)是當系統(tǒng) crash 的時候寂殉,會保存一個 tombstone 文件到/data/tombstones目錄下(Logcat中也會有相應的信息)囚巴,文件就像墓碑一樣記錄了死亡了的進程的基本信息(例如進程的進程 號,線程號)友扰,死亡的地址(在哪個地址上發(fā)生了 Crash)彤叉,死亡時的現場是什么樣的(記錄了一系列的堆棧調用信息)等等。

閃退(tombstone)主要日志如下村怪,中間太長部分用省略號省略秽浇。

    --------- beginning of crash
2020-01-19 15:22:07.194 14414-14414/com.android.dj.crash.test A/libc: Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xfffffffd in tid 14414 (dj.crashtest), pid 14414 (dj.crashtest)
2020-01-19 15:22:07.249 14414-18253/com.android.dj.crash.test V/IOTCAPIS: [io_recv_proc][297]:
2020-01-19 15:22:07.249 14414-18253/com.android.dj.crash.test V/IOTCAPIS: get remote  packet ICE_SES_MSG_HIT
2020-01-19 15:22:07.303 18260-18260/? I/crash_dump32: obtaining output fd from tombstoned, type: kDebuggerdTombstone
2020-01-19 15:22:07.309 883-883/? I//system/bin/tombstoned: received crash request for pid 14414
2020-01-19 15:22:07.311 18260-18260/? I/crash_dump32: performing dump of process 14414 (target tid = 14414)
2020-01-19 15:22:07.313 1313-1416/system_process W/ActivityTaskManager: Activity pause timeout for ActivityRecord{567b991 u0 com.android.dj.crash.test/com.android.dj.crash.view.CrashTestActivity t2302 f}
···
2020-01-19 15:22:07.330 18260-18260/? A/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
2020-01-19 15:22:07.330 18260-18260/? A/DEBUG: Build fingerprint: 'HUAWEI/VOG-AL00/HWVOG:10/HUAWEIVOG-AL00/10.0.0.185C00:user/release-keys'
2020-01-19 15:22:07.330 18260-18260/? A/DEBUG: Revision: '0'
2020-01-19 15:22:07.330 18260-18260/? A/DEBUG: ABI: 'arm'
2020-01-19 15:22:07.331 18260-18260/? A/DEBUG: SYSVMTYPE: Maple
    APPVMTYPE: Art
2020-01-19 15:22:07.331 18260-18260/? A/DEBUG: Timestamp: 2020-01-19 15:22:07+0800
2020-01-19 15:22:07.331 18260-18260/? A/DEBUG: pid: 14414, tid: 14414, name: dj.crashtest  >>> com.android.dj.crash.test <<<
2020-01-19 15:22:07.331 18260-18260/? A/DEBUG: uid: 10218
2020-01-19 15:22:07.331 18260-18260/? A/DEBUG: signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xfffffffd
2020-01-19 15:22:07.331 18260-18260/? A/DEBUG:     r0  fffffffd  r1  ff99f161  r2  80000000  r3  00660e9d
2020-01-19 15:22:07.331 18260-18260/? A/DEBUG:     r4  ffffffff  r5  b9f33000  r6  867cb252  r7  ff99f108
2020-01-19 15:22:07.331 18260-18260/? A/DEBUG:     r8  00000000  r9  eb283e00  r10 ff99f7a0  r11 eb283e00
2020-01-19 15:22:07.331 18260-18260/? A/DEBUG:     ip  20000000  sp  ff99f0c8  lr  00000002  pc  e9097000
2020-01-19 15:22:07.419 2378-10947/? D/HwRecentsTaskUtils: refreshToCache
2020-01-19 15:22:07.419 2378-10947/? D/HwRecentsTaskUtils: searchFromDate
2020-01-19 15:22:07.427 2302-10215/? E/HsmCoreServiceImpl: onTransact in code is: 103
2020-01-19 15:22:07.427 2302-10215/? I/MediaProcessHandler: playingUids: 
···
2020-01-19 15:22:07.581 14414-18186/com.android.dj.crash.test I/IPCSDK: 1
2020-01-19 15:22:07.582 14414-18186/com.android.dj.crash.test V/IOTCAPIS: [p2p_global_thread][94]:
2020-01-19 15:22:07.582 14414-18186/com.android.dj.crash.test V/IOTCAPIS: p2p_global_thread GLOBAL_EVENT_MSG_CB_EVENT_SESSION_CONNECT_SUCCESS_P2P end
2020-01-19 15:22:07.691 18260-18260/? A/DEBUG: backtrace:
2020-01-19 15:22:07.691 18260-18260/? A/DEBUG:       #00 pc 0004f000  /apex/com.android.runtime/lib/bionic/libc.so (__memcpy_a15+200) (BuildId: f2470da1a22265f8104ce6bb9bcaf63e)
2020-01-19 15:22:07.691 18260-18260/? A/DEBUG:       #01 pc 00023d6f  /data/app/com.android.dj.crash.test-dA-LA_OmHFay2acWJnDeJA==/lib/arm/libipcsdk.so (LoopBuffWrite+138) (BuildId: cf6a63bc513797ba7582c510f377f11c44a12970)
2020-01-19 15:22:07.691 18260-18260/? A/DEBUG:       #02 pc 00031f75  /data/app/com.android.dj.crash.test-dA-LA_OmHFay2acWJnDeJA==/lib/arm/libipcsdk.so (CP2PSessionData::p2p_session_data_write(char*, int, unsigned char)+264) (BuildId: cf6a63bc513797ba7582c510f377f11c44a12970)
2020-01-19 15:22:07.691 18260-18260/? A/DEBUG:       #03 pc 0002a561  /data/app/com.android.dj.crash.test-dA-LA_OmHFay2acWJnDeJA==/lib/arm/libipcsdk.so (IOTC_Session_WriteData+66) (BuildId: cf6a63bc513797ba7582c510f377f11c44a12970)
···

2020-01-19 15:22:07.693 18260-18260/? A/DEBUG:       #134 pc 0000202f  /system/bin/app_process32 (_start_main+38) (BuildId: 9979c215af59ed821fac6ea4f956225d)
2020-01-19 15:22:07.693 18260-18260/? A/DEBUG:       #135 pc 00004456  <anonymous:eb84e000>

可以看到
tombstone文件如何分析
主要看backtrace下面的函數調用,backtrace下的函數調用是從下往上的順序執(zhí)行的甚负,所以在最上面的函數是最后執(zhí)行的柬焕。
最后幾行的函數調用如下:

2020-01-19 15:22:07.691 18260-18260/? A/DEBUG: backtrace:
2020-01-19 15:22:07.691 18260-18260/? A/DEBUG:       #00 pc 0004f000  /apex/com.android.runtime/lib/bionic/libc.so (__memcpy_a15+200) (BuildId: f2470da1a22265f8104ce6bb9bcaf63e)
2020-01-19 15:22:07.691 18260-18260/? A/DEBUG:       #01 pc 00023d6f  /data/app/com.android.dj.crash.test-dA-LA_OmHFay2acWJnDeJA==/lib/arm/libipcsdk.so (LoopBuffWrite+138) (BuildId: cf6a63bc513797ba7582c510f377f11c44a12970)
2020-01-19 15:22:07.691 18260-18260/? A/DEBUG:       #02 pc 00031f75  /data/app/com.android.dj.crash.test-dA-LA_OmHFay2acWJnDeJA==/lib/arm/libipcsdk.so (CP2PSessionData::p2p_session_data_write(char*, int, unsigned char)+264) (BuildId: cf6a63bc513797ba7582c510f377f11c44a12970)
2020-01-19 15:22:07.691 18260-18260/? A/DEBUG:       #03 pc 0002a561  /data/app/com.android.dj.crash.test-dA-LA_OmHFay2acWJnDeJA==/lib/arm/libipcsdk.so (IOTC_Session_WriteData+66) (BuildId: cf6a63bc513797ba7582c510f377f11c44a12970)

我們需要記住最后幾個函數調用的地址00023d6f、00031f75梭域、0002a561斑举,后面用到的工具分析以及反匯編后的文件分析都會用到這幾個偏移地址。

分析工具

android的ndk中提供了多個工具可以進行so庫導致的crash的分析病涨。

1)addr2line

addr2line 是 用來獲得指定動態(tài)鏈接庫文件或者可執(zhí)行文件中指定地址對應的源代碼信息的工具

D:\DJ_Software\Android\Ndk_Download\android-ndk-r10e-windows-x86_64\android-ndk-r10e\toolchains\arm-linux-androideabi-4.8\prebuilt\windows-x86_64\bin>arm-linux-androideabi-addr2line -f -e D:\flash_anr_pc\libipcsdk.so 00023d6f
LoopBuffWrite
??:?

D:\DJ_Software\Android\Ndk_Download\android-ndk-r10e-windows-x86_64\android-ndk-r10e\toolchains\arm-linux-androideabi-4.8\prebuilt\windows-x86_64\bin>arm-linux-androideabi-addr2line -f -e D:\flash_anr_pc\libipcsdk.so 00031f75
_ZN15CP2PSessionData22p2p_session_data_writeEPcih
??:?

addr2line 命令及執(zhí)行結果如上所示富玷,-e參數指定文件名,-f參數顯示函數名既穆。只是得到了函數入口凌彬,詳細運行信息沒有。再使用objdump工具看下循衰。

2)objdump

objdump可以將so庫進行反匯編铲敛,反匯編后得到重定向文件,然后根據偏移地址得到更詳細的函數調用上下文信息会钝。

我實際使用ndk 20版本發(fā)現addr2line 運行可以伐蒋,objdump總有一些錯誤,所以最后使用ndk 10命令執(zhí)行成功迁酸。

D:\DJ_Software\Android\Ndk_Download\android-ndk-r10e-windows-x86_64\android-ndk-r10e\toolchains\arm-linux-androideabi-4.8\prebuilt\windows-x86_64\arm-linux-androideabi\bin>objdump -S -D D:\flash_anr_pc\libipcsdk.so > D:\flash_anr_pc\deassmble_libipc.log

命令執(zhí)行結果就是將反匯編后的結果寫入到D盤對應目錄的deassmble_libipc.log文件里先鱼。

反匯編后結果分析

仍是重點分析前面提到的那3個函數。實際發(fā)現反匯編后不知為何得到的函數偏移地址總是比crash日志中的偏移地址小1奸鬓。

IOTC_Session_WriteData函數

打開deassmble_libipc.log文件焙畔,搜索偏移地址“2a560”。

0002a51e <IOTC_Session_WriteData>:
   2a51e:   b5b0        push    {r4, r5, r7, lr}
   2a520:   af02        add r7, sp, #8
   2a522:   b08a        sub sp, #40 ; 0x28
   2a524:   469c        mov ip, r3
   2a526:   4696        mov lr, r2
   2a528:   460c        mov r4, r1
···
   2a560:   f7ea ef62   blx 15428 <_ZN15CP2PSessionData22p2p_session_data_writeEPcih@plt>
   2a564:   9009        str r0, [sp, #36]   ; 0x24
   2a566:   e7ff        b.n 2a568 <IOTC_Session_WriteData+0x4a>
   2a568:   9809        ldr r0, [sp, #36]   ; 0x24
   2a56a:   b00a        add sp, #40 ; 0x28
   2a56c:   bdb0        pop {r4, r5, r7, pc}

可以看到IOTC_Session_WriteData函數在2a560行(crash日志中是0002a561)調用了p2p_session_data_write函數串远,p2p_session_data_write函數是C++類中的成員函數宏多,所以在匯編中的函數名與純C函數的函數名有所區(qū)別儿惫。

p2p_session_data_write函數

00031e6c <_ZN15CP2PSessionData22p2p_session_data_writeEPcih>:
   31e6c:   b5f0        push    {r4, r5, r6, r7, lr}
   31e6e:   af03        add r7, sp, #12
   31e70:   f84d bd04   str.w   fp, [sp, #-4]!
   31e74:   b098        sub sp, #96 ; 0x60
   31e76:   469c        mov ip, r3
   31e78:   4696        mov lr, r2
···
   31f66:   d923        bls.n   31fb0 <_ZN15CP2PSessionData22p2p_session_data_writeEPcih+0x144>
   31f68:   e7ff        b.n 31f6a <_ZN15CP2PSessionData22p2p_session_data_writeEPcih+0xfe>
   31f6a:   9808        ldr r0, [sp, #32]
   31f6c:   f500 7067   add.w   r0, r0, #924    ; 0x39c
   31f70:   a914        add r1, sp, #80 ; 0x50
   31f72:   2209        movs    r2, #9
   31f74:   f7e2 ea0c   blx 14390 <LoopBuffWrite@plt>
   31f78:   9910        ldr r1, [sp, #64]   ; 0x40
   31f7a:   2901        cmp r1, #1
   31f7c:   9005        str r0, [sp, #20]
   31f7e:   db09        blt.n   31f94 <_ZN15CP2PSessionData22p2p_session_data_writeEPcih+0x128>

可以看到實際的LoopBuffWrite函數調用在31f74行(crash日志中的00031f75)。

LoopBuffWrite函數

00023ce4 <LoopBuffWrite>:
   23ce4:   b5d0        push    {r4, r6, r7, lr}
   23ce6:   af02        add r7, sp, #8
   23ce8:   b08c        sub sp, #48 ; 0x30
   23cea:   4613        mov r3, r2
   23cec:   468c        mov ip, r1
   23cee:   4686        mov lr, r0
···
   23d64:   3a01        subs    r2, #1
   23d66:   4010        ands    r0, r2
   23d68:   4408        add r0, r1
   23d6a:   990a        ldr r1, [sp, #40]   ; 0x28
   23d6c:   9a08        ldr r2, [sp, #32]
   23d6e:   f7f0 ecde   blx 1472c <__aeabi_memcpy@plt>
   23d72:   990b        ldr r1, [sp, #44]   ; 0x2c
   23d74:   6809        ldr r1, [r1, #0]
   23d76:   9a0a        ldr r2, [sp, #40]   ; 0x28
   23d78:   f8dd e020   ldr.w   lr, [sp, #32]

中間部分代碼省略伸但,可以看到在23d6e行(crash日志中為00023d6f)肾请,也是差一行。LoopBuffWrite在此處執(zhí)行了__aeabi_memcpy更胖,估計是執(zhí)行數據拷貝時發(fā)生了錯誤铛铁,再繼續(xù)深入就需要對匯編語言有所了解。
最后却妨,還有一個工具ndk-stack可以簡化分析過程饵逐。使用參見
https://blog.csdn.net/u010144805/article/details/80763956

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市彪标,隨后出現的幾起案子梳毙,更是在濱河造成了極大的恐慌,老刑警劉巖捐下,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異萌业,居然都是意外死亡坷襟,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進店門生年,熙熙樓的掌柜王于貴愁眉苦臉地迎上來婴程,“玉大人,你說我怎么就攤上這事抱婉〉凳澹” “怎么了?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵蒸绩,是天一觀的道長衙四。 經常有香客問我,道長患亿,這世上最難降的妖魔是什么传蹈? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮步藕,結果婚禮上惦界,老公的妹妹穿的比我還像新娘。我一直安慰自己咙冗,他們只是感情好沾歪,可當我...
    茶點故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著雾消,像睡著了一般灾搏。 火紅的嫁衣襯著肌膚如雪挫望。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天确镊,我揣著相機與錄音士骤,去河邊找鬼。 笑死蕾域,一個胖子當著我的面吹牛拷肌,可吹牛的內容都是我干的。 我是一名探鬼主播旨巷,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼巨缘,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了采呐?” 一聲冷哼從身側響起若锁,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎斧吐,沒想到半個月后又固,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡煤率,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年仰冠,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蝶糯。...
    茶點故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡洋只,死狀恐怖,靈堂內的尸體忽然破棺而出昼捍,到底是詐尸還是另有隱情识虚,我是刑警寧澤,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布妒茬,位于F島的核電站担锤,受9級特大地震影響,放射性物質發(fā)生泄漏乍钻。R本人自食惡果不足惜妻献,卻給世界環(huán)境...
    茶點故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望团赁。 院中可真熱鬧育拨,春花似錦、人聲如沸欢摄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽怀挠。三九已至析蝴,卻和暖如春害捕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背闷畸。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工尝盼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人佑菩。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓盾沫,卻偏偏與公主長得像,于是被迫代替她去往敵國和親殿漠。 傳聞我的和親對象是個殘疾皇子赴精,可洞房花燭夜當晚...
    茶點故事閱讀 43,697評論 2 351

推薦閱讀更多精彩內容

  • 到斯德哥爾摩一個多月,感觸頗淺绞幌。想著一個月寫出一個月的感受蕾哟,于是提筆。 12月份的北歐莲蜘,白天短谭确,黑夜長,灰蒙蒙票渠,霧...
    炸醬面的二喜閱讀 453評論 4 1