addr2line 和 tombstone問題分析

        做安卓開發的同學對於tombstone問題應該是很熟悉了,但是對於如何排查和分析值得總結和整理的,這篇文章對入門安卓開發的技術來說是個入門指導,同時對安卓開發的中高級開發也有借鑑。

首先我們來說下什麼是tombstone  :

   當一個動態庫(native 程序)開始執行時,系統會註冊一些連接到 debuggerd 的 signal handlers,當系統 crash 的時候,會保存一個 tombstone 文件到/data/tombstones目錄下(Logcat中也會有相應的信息),文件的確就像墓碑一樣記錄了死亡了的進程的基本信息(例如進程的進程 號,線程號),死亡的地址(在哪個地址上發生了 Crash),死亡時的現場是什麼樣的(記錄了一系列的堆棧調用信息)等等。 

    舉例來看一個tombstone文件:

一個tombstone文件大概包含以下信息

--------- beginning of crash
F/libc    (  244): invalid address or address of corrupt block 0xb82f54a0 passed to dlfree
I/libc    (  244): debuggerd_signal_handler called: signal=11, fn=0xb6fbdaa1
F/libc    (  244): Fatal signal 11 (SIGSEGV), code 1, fault addr 0xdeadbaad in tid 244 (mediaserver)
I/libc    (  244): exit from debuggerd_signal_handler
W/NativeCrashListener(  916): Couldn't find ProcessRecord for pid 244
I/DEBUG   (  241): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
E/DEBUG   (  241): AM write failure (32 / Broken pipe)
I/DEBUG   (  241): Build fingerprint: XXXXXXXXX
I/DEBUG   (  241): Revision: '0'
I/DEBUG   (  241): ABI: 'arm'
I/DEBUG   (  241): pid: 244, tid: 244, name: mediaserver  >>> /system/bin/mediaserver <<<
I/DEBUG   (  241): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xdeadbaad
I/art     ( 3078): now dumpable=1
I/DEBUG   (  241): Abort message: 'invalid address or address of corrupt block 0xb82f54a0 passed to dlfree'
I/DEBUG   (  241):     r0 00000000  r1 b6f20dec  r2 deadbaad  r3 00000000
I/DEBUG   (  241):     r4 b82f54a0  r5 b6f220f8  r6 00000000  r7 42424242
I/DEBUG   (  241):     r8 ffffffff  r9 b82f5460  sl 00000030  fp 00000000
I/DEBUG   (  241):     ip 00000000  sp beb2c020  lr b6ef1fa7  pc b6ef1fa8  cpsr 600e0030
I/DEBUG   (  241):     d0  0000000000000000  d1  6f2073736572646c
I/DEBUG   (  241):     d2  707572726f632066  d3  206b636f6c622072
I/DEBUG   (  241):     d4  4242424242424242  d5  4242424242424242
I/DEBUG   (  241):     d6  4242424242424242  d7  3ecccccd42424242
I/DEBUG   (  241):     d8  0000000000000000  d9  0000000000000000
I/DEBUG   (  241):     d10 0000000000000000  d11 0000000000000000
I/DEBUG   (  241):     d12 0000000000000000  d13 0000000000000000
I/DEBUG   (  241):     d14 0000000000000000  d15 0000000000000000
I/DEBUG   (  241):     d16 0000000000000000  d17 3ff0000000000000
I/DEBUG   (  241):     d18 7e37e43c8800759c  d19 bfd5f3f082400000
I/DEBUG   (  241):     d20 3e66376972bea4d0  d21 bf66b12699b6468f
I/DEBUG   (  241):     d22 3fc54aa75950670f  d23 bfd73498f0a5ef3a
I/DEBUG   (  241):     d24 3fe0000000000000  d25 bfaaf3ec933c988f
I/DEBUG   (  241):     d26 0000000000000000  d27 4000000000000000
I/DEBUG   (  241):     d28 4002e6931e14bde7  d29 3faaf3ec9198f99c
I/DEBUG   (  241):     d30 3ff0000000000000  d31 3fd29572efd86cee
I/DEBUG   (  241):     scr 20000010
I/DEBUG   (  241): 
I/DEBUG   (  241): backtrace:
I/DEBUG   (  241):     #00 pc 00028fa8  /system/lib/libc.so (dlfree+1239)
I/DEBUG   (  241):     #01 pc 0000f2cb  /system/lib/libc.so (free+10)
I/DEBUG   (  241):     #02 pc 0000a1cb  /system/lib/libstagefright_foundation.so (_ZN7android7ABufferD2Ev+42)
I/DEBUG   (  241):     #03 pc 0000a211  /system/lib/libstagefright_foundation.so (_ZN7android7ABufferD0Ev+4)
I/DEBUG   (  241):     #04 pc 0000d68d  /system/lib/libutils.so (_ZNK7android7RefBase9decStrongEPKv+40)
I/DEBUG   (  241):     #05 pc 0005adfd  /system/lib/libstagefright.so (_ZN7android2spINS_13GraphicBufferEED2Ev+10)
I/DEBUG   (  241):     #06 pc 0007cd0f  /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor10parseChunkEPxi+634)
I/DEBUG   (  241):     #07 pc 0007d43d  /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor10parseChunkEPxi+2472)
I/DEBUG   (  241):     #08 pc 0007e873  /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor12readMetaDataEv+58)
I/DEBUG   (  241):     #09 pc 0007eaa1  /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor11countTracksEv+4)
I/DEBUG   (  241):     #10 pc 000acf9d  /system/lib/libstagefright.so (_ZN7android13ExtendedUtils29MediaExtractor_CreateIfNeededENS_2spINS_14MediaExtractorEEERKNS1_INS_10DataSourceEEEPKc+60)
I/DEBUG   (  241):     #11 pc 0008e3f5  /system/lib/libstagefright.so (_ZN7android14MediaExtractor6CreateERKNS_2spINS_10DataSourceEEEPKc+624)
I/DEBUG   (  241):     #12 pc 0006ace9  /system/lib/libstagefright.so (_ZN7android13AwesomePlayer15setDataSource_lERKNS_2spINS_10DataSourceEEE+12)
I/DEBUG   (  241):     #13 pc 0006c0dd  /system/lib/libstagefright.so (_ZN7android13AwesomePlayer13setDataSourceEixx+228)
I/DEBUG   (  241):     #14 pc 0003d647  /system/lib/libmediaplayerservice.so (_ZN7android18MediaPlayerService6Client13setDataSourceEixx+362)
I/DEBUG   (  241):     #15 pc 0005ea03  /system/lib/libmedia.so (_ZN7android13BnMediaPlayer10onTransactEjRKNS_6ParcelEPS1_j+478)
I/DEBUG   (  241):     #16 pc 00017fad  /system/lib/libbinder.so (_ZN7android7BBinder8transactEjRKNS_6ParcelEPS1_j+60)
I/DEBUG   (  241):     #17 pc 0001cfdb  /system/lib/libbinder.so (_ZN7android14IPCThreadState14executeCommandEi+562)
I/DEBUG   (  241):     #18 pc 0001d12f  /system/lib/libbinder.so (_ZN7android14IPCThreadState20getAndExecuteCommandEv+38)
I/DEBUG   (  241):     #19 pc 0001d171  /system/lib/libbinder.so (_ZN7android14IPCThreadState14joinThreadPoolEb+48)
I/DEBUG   (  241):     #20 pc 00001721  /system/bin/mediaserver
I/DEBUG   (  241):     #21 pc 0000f411  /system/lib/libc.so (__libc_init+44)
I/DEBUG   (  241):     #22 pc 00001998  /system/bin/mediaserver
I/DEBUG   (  241): 
I/DEBUG   (  241): stack:
I/DEBUG   (  241):          beb2bfe0  00000000  
I/DEBUG   (  241):          beb2bfe4  29ec038f  
I/DEBUG   (  241):          beb2bfe8  0009eb34  
I/DEBUG   (  241):          beb2bfec  b82f54a0  [heap]
I/DEBUG   (  241):          beb2bff0  b6f220f8  
I/DEBUG   (  241):          beb2bff4  00000000  
I/DEBUG   (  241):          beb2bff8  42424242  
I/DEBUG   (  241):          beb2bffc  b6edb3d1  /system/lib/libc.so (__libc_fatal_no_abort+16)
I/DEBUG   (  241):          beb2c000  b6f12f97  /system/lib/libc.so
I/DEBUG   (  241):          beb2c004  beb2c014  [stack]
I/DEBUG   (  241):          beb2c008  b6f167be  /system/lib/libc.so
I/DEBUG   (  241):          beb2c00c  b6ef1fa7  /system/lib/libc.so (dlfree+1238)
I/DEBUG   (  241):          beb2c010  b6f12f97  /system/lib/libc.so
I/DEBUG   (  241):          beb2c014  b82f54a0  [heap]
I/DEBUG   (  241):          beb2c018  b6f167be  /system/lib/libc.so
I/DEBUG   (  241):          beb2c01c  b82f54b0  [heap]
I/DEBUG   (  241):     #00  beb2c020  b82f5460  [heap]
......

它包含了發生問題的進程ID信息

I/DEBUG   (  241): pid: 244, tid: 244, name: mediaserver  >>> /system/bin/mediaserver <<<

當 tid == pid 時,問題發生在父進程,反之問題發生在子進程,從上面的日誌信息可以看出發生問題的進程是mediaserver的子進程。

Terminated signal 和 fault address 信息

F/libc    (  244): Fatal signal 11 (SIGSEGV), code 1, fault addr 0xdeadbaad in tid 244 (mediaserver)

這裏的信息說明出現進程 Crash 的原因是因爲程序產生了段錯誤的信號,訪問了非法的內存空間,而訪問的非法地址是 0xdeadbaad。

 

當然這個是比較簡單的,稍微複雜一些的,需要查看崩潰的堆棧所在文件和代碼行,那麼我們可以借鑑addr2line工具來分析。

addr2line工具是一個可以將指令的地址和可執行映像轉換爲文件名、函數名和源代碼行數的工具。這在內核執行過程中出現崩潰時,可用於快速定位出出錯的位置,進而找出代碼的bug。

用法:

addr2line [-a| --addresses ] [-b bfdname | --target=bfdname] [-C | --demangle[=style]] [-e filename | --exe=filename] [-f | --function] [-s | --basename] [-i | --inlines] [-p | --pretty-print] [-j | --section=name] [-H | --help] [-V | --version] [addr addr ...] 

這裏對參數說明下:

-a --addresses:在函數名、文件和行號信息之前,顯示地址,以十六進制形式。
-b --target=<bfdname>:指定目標文件的格式爲bfdname。
-e --exe=<executable>:指定需要轉換地址的可執行文件名。
-i --inlines : 如果需要轉換的地址是一個內聯函數,則輸出的信息包括其最近範圍內的一個非內聯函數的信息。
-j --section=<name>:給出的地址代表指定section的偏移,而非絕對地址。
-p --pretty-print:使得該函數的輸出信息更加人性化:每一個地址的信息佔一行。
-s --basenames:僅僅顯示每個文件名的基址(即不顯示文件的具體路徑,只顯示文件名)。
-f --functions:在顯示文件名、行號輸出信息的同時顯示函數名信息。
-C --demangle[=style]:將低級別的符號名解碼爲用戶級別的名字。
-h --help:輸出幫助信息。
-v --version:輸出版本號。

所以對於上邊的tombstone文件我們藉助工具來分析:   addr2line   -Cfse     so動態庫/exe路徑         地址address

就能根據輸出來看到對應的cpp文件 和對應行數來分析。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章