2015-11-24 1 views
1

Notre application a des millions d'utilisateurs, et nous avons rencontré un problème de plantage Wicked lorsque nous essayons de charger notre privé dans un thread de travail, environ 0,01% de nos utilisateurs vont planter pendant System.load(). Log comme:Android crash nativeLoad

608dd000-608de000 r--p 00000000 b3:07 8514  /data/data/com.UCMobile/com/core/version.0/lib/libWebCore_UC.so 
Thread Name: '<unregistered>' 
pid: 16879, tid: 16947 >>> com.UCMobile <<< 
signal 7 (SIGBUS), code 2 (BUS_ADRERR), fault addr 61e3eb64 
r0 61e3eb64 r1 00000000 r2 00000480 r3 c0000000 
r4 00000000 r5 00000000 r6 00000000 r7 00000000 
r8 000e7094 r9 00000005 10 6110a000 fp 0000006b 
ip 00000000 sp 60bec8c8 lr 00000000 pc 40062698 cpsr a0000010 

    #00 pc 40062698 /system/bin/linker 
    #01 pc 40061ce0 /system/bin/linker 
    #02 pc 4005fc22 /system/bin/linker 
    #03 pc 40060172 /system/bin/linker 
    #04 pc 400614fe /system/bin/linker 
    #05 pc 0006755c /system/lib/libdvm.so 
    #06 pc 00091f68 /system/lib/libdvm.so 
    #07 pc 000273a0 /system/lib/libdvm.so 
    #08 pc 0002b2dc /system/lib/libdvm.so 
    #09 pc 00084e44 /system/lib/libdvm.so 
    #10 pc 00093f98 /system/lib/libdvm.so 
    #11 pc 000273a0 /system/lib/libdvm.so 
    #12 pc 0002b2dc /system/lib/libdvm.so 
    #13 pc 00084a94 /system/lib/libdvm.so 
    #14 pc 00084b20 /system/lib/libdvm.so 
    #15 pc 000700f8 /system/lib/libdvm.so 
    #16 pc 0000e4a4 /system/lib/libc.so 

    >>> [Dalvik stack info] <<< 
    at java.lang.Runtime.nativeLoad(Native Method) 
    at java.lang.Runtime.load(Runtime.java:339) 
    at java.lang.System.load(System.java:500) 

Et quand nous avons regardé dans le code de liaison, nous avons compris la ligne de code où l'application est écrasé: http://androidxref.com/4.4.4_r1/xref/bionic/linker/linker_phdr.cpp#348

bool ElfReader::LoadSegments() { 

347 if ((phdr->p_flags & PF_W) != 0 && PAGE_OFFSET(seg_file_end) > 0) { 
348  memset((void*)seg_file_end, 0, PAGE_SIZE - PAGE_OFFSET(seg_file_end)); --> crash when memset 
349 } 
350 

Dans la plupart des cas, adr défaut est égal à « seg_file_end ". (Nous pouvons le vérifier par l'info de readelf -l libWebCore_UC.so.) Et si un utilisateur plante comme ceci, il va planter encore et encore. (Certains utilisateurs se sont plantés des centaines de fois.)

Et nous avons vérifié sa taille avant de le charger, sa taille doit être la même que nous attendons.

La plupart de ces types de crash sont sigbus, parfois SIGSEGV. Quelqu'un a une idée à ce sujet?

+0

"il va planter encore et encore" - désinstalle-t-il et installe-t-il une nouvelle aide? –

+0

Oui, 'adb shell pm clear com.UCMobile' semble aussi aider. –

+3

Ce problème peut être le résultat de si corrompu. –

Répondre

0

Se référant au code du noyau Linux:

int filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) 
{ 
    int error; 
    struct file *file = vma->vm_file; 
    struct address_space *mapping = file->f_mapping; 
    struct file_ra_state *ra = &file->f_ra; 
    struct inode *inode = mapping->host; 
    pgoff_t offset = vmf->pgoff; 
    struct page *page; 
    loff_t size; 
    int ret = 0; 

    size = round_up(i_size_read(inode), PAGE_SIZE); 
    if (offset >= size >> PAGE_SHIFT) 
     return VM_FAULT_SIGBUS; 
... 
    /* Things didn't work out. Return zero to tell the mm layer so. */ 
    shrink_readahead_size_eio(file, ra); 
    return VM_FAULT_SIGBUS; 
} 

Il a deux situations d'échec. L'un d'eux est que la taille du fichier n'est pas assez grande pour couvrir le vma, l'autre est la lecture du système de fichiers a échoué.

Et vous devriez me demander avant de poster ceci.