WebView相容問題分析報告

來源:互聯網
上載者:User

標籤:fse   cee   asi   越界   st3   magic   oid   goto   backtrac   

【NE現場】

pid: 6715, tid: 6719, name: Signal Catcher >>> com.android.contacts <<<signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x55a5931480x0 00000000000d4000 x1 0000007f98f9d868 x2 0000000000004001 x3 0000007f951f4450x4 00000000000000ca x5 0000000000004001 x6 0000000000000000 x7 0000007f98f9d86cx8 0000000000001a3f x9 0000000000001a3f x10 0000007f98f9d86c x11 0000000000004000x12 0000000000004001 x13 0000000000000000 x14 0000000000000001 x15 0000000000000fc0x16 0000007f98f90a58 x17 0000000000000000 x18 0000000000000fc0 x19 0000007f97457000x20 0000007f98f9df18 x21 00000055a5931460 x22 0000007f951f3420 x23 00000055a585d460x24 0000007f951f3428 x25 00000000000000ca x26 0000000000000001 x27 0000007f951f3338x28 0000007f8abba350 x29 0000007f951f3290 x30 0000007f97434788sp 0000007f951f3290 pc 0000007f974347b0 pstate 0000000060000000backtrace:#00 pc 00000000000077b0 /system/lib64/libunwind.so#01 pc 0000000000007cf4 /system/lib64/libunwind.so (_ULaarch64_dwarf_find_debug_frame+320)#02 pc 0000000000008244 /system/lib64/libunwind.so#03 pc 0000000000003868 /system/bin/linker64 (_dlZ18do_dl_iterate_phdrPFiP12dl_phdr_infomPvES1+96)#04 pc 0000000000003324 /system/bin/linker64 (__dl_dl_iterate_phdr+44)#05 pc 00000000000085b8 /system/lib64/libunwind.so#06 pc 00000000000062c0 /system/lib64/libunwind.so#07 pc 00000000000071f4 /system/lib64/libunwind.so#08 pc 0000000000007618 /system/lib64/libunwind.so#09 pc 0000000000015ca8 /system/lib64/libunwind.so (_ULaarch64_step+40)#10 pc 0000000000006f80 /system/lib64/libbacktrace.so (_ZN13UnwindCurrent17UnwindFromContextEmP8ucontext+360)#11 pc 0000000000004eec /system/lib64/libbacktrace.so (_ZN16BacktraceCurrent12UnwindThreadEm+556)#12 pc 000000000048a368 /system/lib64/libart.so (ZN3art15DumpNativeStackERNSt3_113basic_ostreamIcNS0_11char_traitsIcEEEEiP12BacktraceMapPKcPNS_9ArtMethodEPv+200)#13 pc 0000000000459204 /system/lib64/libart.so (ZNK3art6Thread4DumpERNSt3_113basic_ostreamIcNS1_11char_traitsIcEEEEP12BacktraceMap+224)#14 pc 00000000004660a4 /system/lib64/libart.so (_ZN3art14DumpCheckpoint3RunEPNS_6ThreadE+692)#15 pc 00000000004670a0 /system/lib64/libart.so (_ZN3art10ThreadList13RunCheckpointEPNS_7ClosureE+500)#16 pc 000000000046770c /system/lib64/libart.so (ZN3art10ThreadList4DumpERNSt3_113basic_ostreamIcNS1_11char_traitsIcEEEE+204)#17 pc 0000000000468014 /system/lib64/libart.so (ZN3art10ThreadList14DumpForSigQuitERNSt3_113basic_ostreamIcNS1_11char_traitsIcEEEE+492)#18 pc 00000000004313a4 /system/lib64/libart.so (ZN3art7Runtime14DumpForSigQuitERNSt3_113basic_ostreamIcNS1_11char_traitsIcEEEE+96)#19 pc 000000000043e814 /system/lib64/libart.so (_ZN3art13SignalCatcher13HandleSigQuitEv+1256)#20 pc 000000000043f424 /system/lib64/libart.so (_ZN3art13SignalCatcher3RunEPv+452)#21 pc 0000000000067754 /system/lib64/libc.so (ZL15_pthread_startPv+52)#22 pc 000000000001c644 /system/lib64/libc.so (__start_thread+16)

從調用棧來看,是SignalCacher線程在列印其他線程的調用棧時出現異常。

 

【問題分析】

先通過addr2line工具確定出問題的代碼:

static intload_debug_frame (const char *file, char **buf, size_t *bufsize, int is_local){  ...  f = fopen (file, "r");  if (!f)    return 1;  if (fread (&ehdr, sizeof (Elf_W (Ehdr)), 1, f) != 1)    goto file_error;  shstrndx = ehdr.e_shstrndx;  Debug (4, "opened file ‘%s‘. Section header at offset %d\n",         file, (int) ehdr.e_shoff);  fseek (f, ehdr.e_shoff, SEEK_SET);  sec_hdrs = calloc (ehdr.e_shnum, sizeof (Elf_W (Shdr)));  if (sec_hdrs == NULL || fread (sec_hdrs, sizeof (Elf_W (Shdr)), ehdr.e_shnum, f) != ehdr.e_shnum)    goto file_error;  Debug (4, "loading string table of size %ld\n",       (long) sec_hdrs[shstrndx].sh_size);  size_t sec_size = sec_hdrs[shstrndx].sh_size;  <<<

看起來是shstrndx太大,數組訪問越界導致的。而

shstrndx = ehdr.e_shstrndx

這個值是從elfheader中擷取的,可能是elf檔案格式有問題。

 

通過objdump反組譯碼,確定這裡ehdr的地址是x27值,也就是0000007f951f3338

再通過tombstone,確定這個ehdr的值為:

memory near x27:    0000007f951f3318 0000007f8371b214 0000007f951f3bb0  ..q......;......    0000007f951f3328 0000007f95c31000 0000007f95c31000  ................    0000007f951f3338 0800000a04034b50 c1963a2100000000  PK..........!:..    0000007f951f3348 3b4e00013b4e66df 7361000d001d0001  .fN;..N;......as    0000007f951f3358 7268632f73746573 5f3030315f656d6f  sets/chrome_100_    0000007f951f3368 2e746e6563726570 350000cafe6b6170  percent.pak....5    0000007f951f3378 2190b2bd990eaa19 0000007f951f3470  .......!p4......

標準的elf檔案,它的檔案頭是一個magic numbers = 7f 45 4c 46,如:

$ xxd symbols/system/bin/linker0000000: 7f45 4c46 0101 0100 0000 0000 0000 0000  .ELF............0000010: 0300 2800 0100 0000 5816 0000 3400 0000  ..(.....X...4...0000020: a430 1800 0000 0005 3400 2000 0a00 2800  .0......4. ...(.0000030: 2300 2000 0600 0000 3400 0000 3400 0000  #. .....4...4...0000040: 3400 0000 4001 0000 4001 0000 0400 0000  [email protected]@.......

而上面的magic numbers是PK,這個是apk包的magic numbers。

當前被解析的時apk包,這個並不是一個elf檔案,因此unwind解析時會出錯。

下一步就需要找到這個elf檔案。為此我們首先得找到正在被列印的目標線程。

 

我們可以在tombstone中搜尋[vdso]就能找到這個正在被列印的線程,如:

pid: 6715, tid: 6762, name: Chrome_FileUser >>> com.android.contacts <<<backtrace:#00 pc 00000000000199c0 /system/lib64/libc.so (syscall+28)#01 pc 0000000000067474 /system/lib64/libc.so (ZL33_pthread_cond_timedwait_relativeP23pthread_cond_internal_tP15pthread_mutex_tPK8timespec+96)#02 pc 00000000000675f0 /system/lib64/libc.so (pthread_cond_timedwait+72)#03 pc 00000000000068bc /system/lib64/libbacktrace.so (_ZN11ThreadEntry4WaitEi+76)#04 pc 0000000000004c3c /system/lib64/libbacktrace.so#05 pc 00000000000004dc [vdso]#06 pc 00000000000199bc /system/lib64/libc.so (syscall+24)#07 pc 0000000000067474 /system/lib64/libc.so (ZL33_pthread_cond_timedwait_relativeP23pthread_cond_internal_tP15pthread_mutex_tPK8timespec+96)#08 pc 0000000000793214 /system/app/WebViewGoogle/WebViewGoogle.apk (offset 0xa0d000)

這裡的vdso是放訊號處理函數的記憶體段:

    ...    0000007f‘993ae000-0000007f‘993aefff r-x         0      1000  [vdso]    0000007f‘993af000-0000007f‘993affff r--     32000      1000  /system/bin/linker64    0000007f‘993b0000-0000007f‘993b1fff rw-     33000      2000  /system/bin/linker64    ...

 

【列印目標線程調用棧過程】

1、給目標線程發送特殊的signal,觸發目標線程的訊號處理函數。

2、核心調用訊號處理函數時,會將當前目標線程的CPU上下文以參數的形式傳給訊號處理函數。這樣訊號處理函數中,就能得到這個上下文。

3、得到這個上下文後,當前線程就將這個上下文傳給Signal Catcher線程,然後自己進入wait狀態。

4、Signal Catcher線程得到這個上下文後,就可以調用unwind庫,來列印目標線程的調用棧,列印完在wake目標線程。

 

當前的NE就是第4個階段,也就是Signal Cacher線程拿到目標線程上下文後,再調用unwind庫解析目標線程的調用棧時出的問題。

從調用棧中可以清楚的看到,是調用棧中有WebViewGoogle.apk這個檔案,和之前的推理吻合。

查看WebViewGoogle.apk的內容,也和前面解析的檔案頭內容相同。

 

【解決方案】

在unwind中,讀取檔案頭後,先判斷是否有elf的magic number即可,如:

  if (fread (&ehdr, sizeof (Elf_W (Ehdr)), 1, f) != 1)    goto file_error;  /* Verify this is actually an elf file. */+ if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0)+   goto file_error;  shstrndx = ehdr.e_shstrndx;

 

aosp中也有相同change:

https://android-review.googlesource.com/#/c/194457/

 

WebView相容問題分析報告

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.