美文网首页
Android利用addr2line分析traces.txt

Android利用addr2line分析traces.txt

作者: wbxjack | 来源:发表于2017-06-05 11:54 被阅读242次

    traces文件

    android出现anr后会在手机中生成如下文件/data/anr/traces.txt。
    利用adb pull取出后,就可以分析啦。

    addr2line

    addr2line是用来解析符号表的工具,是个python3的脚本,可以根据自己的需求修改。命令如下:python3 addr2line.py -dump traces.txt -sym 源码/out/target/product/xxx/symbols/ -cpp -force 然后可以重定向新的文件方便查看。

    例子

    场景

    手机otg连接u盘,里面有很多音频/视频/图片,然后用文件管理器查看,加载的过程中,拔掉otg线,手机卡顿,然后systemUI出现anr

    log文件

    05-25 15:42:56.936 2654 2719 E ActivityManager: ANR in com.android.systemui
    05-25 15:42:56.936 2654 2719 E ActivityManager: PID: 3111
    05-25 15:42:56.936 2654 2719 E ActivityManager: Reason: Broadcast of Intent 
    { act=android.intent.action.TIME_TICK flg=0x50000014 (has extras) } 
    05-25 15:42:56.936 2654 2719 E ActivityManager: Load: 13.84 / 9.53 / 7.99
    05-25 15:42:56.936 2654 2719 E ActivityManager: CPU usage from 0ms to 29604ms later (2017-05-25 15:42:27.293 to 2017-05-25 15:42:56.896):
    05-25 15:42:56.936 2654 2719 E ActivityManager: 94% 25870/sdcard: 5.3% user + 88% kernel / faults: 8 minor 
    05-25 15:42:56.936 2654 2719 E ActivityManager: 11% 25375/kworker/u8:0: 0% user + 11% kernel
    05-25 15:42:56.936 2654 2719 E ActivityManager: 7.9% 25397/kworker/u8:4: 0% user + 7.9% kernel
    05-25 15:42:56.936 2654 2719 E ActivityManager: 7.6% 25885/kworker/u8:5: 0% user + 7.6% kernel
    05-25 15:42:56.936 2654 2719 E ActivityManager: 7.3% 2654/system_server: 4.4% user + 2.9% kernel / faults: 2445 minor 37 major 
    05-25 15:42:56.936 2654 2719 E ActivityManager: 6.3% 20769/kworker/u8:8: 0% user + 6.3% kernel
    05-25 15:42:56.936 2654 2719 E ActivityManager: 3.2% 23494/com.cloudminds.filemanager: 1.6% user + 1.5% kernel / faults: 1995 minor 
    05-25 15:42:56.936 2654 2719 E ActivityManager: 2.7% 24528/com.baidu.searchbox: 1.9% user + 0.7% kernel / faults: 757 minor 42 major 
    05-25 15:42:56.936 2654 2719 E ActivityManager: 1.9% 390/irq/431-fsc_int: 0% user + 1.9% kernel
    05-25 15:42:56.936 2654 2719 E ActivityManager: 1.5% 8/rcu_sched: 0% user + 1.5% kernel
    05-25 15:42:56.936 2654 2719 E ActivityManager: 1.5% 7/rcu_preempt: 0% user + 1.5% kernel
    05-25 15:42:56.936 2654 2719 E ActivityManager: 1% 4149/com.android.phone: 0.4% user + 0.6% kernel / faults: 1469 minor 14 major 
    05-25 15:42:56.936 2654 2719 E ActivityManager: 0.8% 11/migration/1: 0% user + 0.8% kernel
    

    发现sdcard中的kernel调用占用大量cpu导致systemUI出现anr。

    trace文件

    25870/sdcard: 5.3% user + 88% kernel
    直接查看trace文件中的pid是25870的sdard相关内容

    ----- pid 25870 at 2017-05-25 15:42:53 -----
    Cmd line: /system/bin/sdcard
    ABI: 'arm64'
    
    "sdcard" sysTid=25870
      #00 pc 000000000006b4f0  /system/lib64/libc.so (read+4)
      #01 pc 000000000000290c  /system/bin/sdcard
      #02 pc 000000000001a7d8  /system/lib64/libc.so (__libc_init+88)
      #03 pc 0000000000001ca0  /system/bin/sdcard
    
    "sdcard" sysTid=25871
      #00 pc 000000000006aa44  /system/lib64/libc.so (__getdents64+8)
      #01 pc 000000000001e36c  /system/lib64/libc.so (readdir+100)
      #02 pc 0000000000004d80  /system/bin/sdcard
      #03 pc 00000000000037f8  /system/bin/sdcard
      #04 pc 0000000000068618  /system/lib64/libc.so (_ZL15__pthread_startPv+196)
      #05 pc 000000000001df68  /system/lib64/libc.so (__start_thread+16)
    
    "sdcard" sysTid=25872
      #00 pc 000000000006b4f0  /system/lib64/libc.so (read+4)
      #01 pc 0000000000002fd8  /system/bin/sdcard
      #02 pc 0000000000068618  /system/lib64/libc.so (_ZL15__pthread_startPv+196)
      #03 pc 000000000001df68  /system/lib64/libc.so (__start_thread+16)
    
    "sdcard" sysTid=25873
      #00 pc 000000000006b4f0  /system/lib64/libc.so (read+4)
      #01 pc 0000000000002fd8  /system/bin/sdcard
      #02 pc 0000000000068618  /system/lib64/libc.so (_ZL15__pthread_startPv+196)
      #03 pc 000000000001df68  /system/lib64/libc.so (__start_thread+16)
    
    ----- end 25870 -----
    

    发现都是libc和sdcard的相关堆栈,不知道是具体哪个函数,所以要用addr2line通过符号表解析出来。

    addr2line解析结果

    用最开始的例子的命令格式解析后,找到sdcard相关内容如下

    "sdcard" sysTid=25870
    #00 pc 000000000006b4f0 /system/lib64/libc.so read 于 read.S:7
    #01 pc 000000000000290c /system/bin/sdcard read 于 unistd.h:465
    (已内连入) watch_package_list 于 sdcard.c:1944
    (已内连入) run 于 sdcard.c:2123
    (已内连入) main 于 sdcard.c:2325
    #02 pc 000000000001a7d8 /system/lib64/libc.so __libc_init 于 libc_init_dynamic.cpp:119
    #03 pc 0000000000001ca0 /system/bin/sdcard do_arm64_start 于 sdcard.c:?
    "sdcard" sysTid=25871
    #00 pc 000000000006aa44 /system/lib64/libc.so __getdents64 于 __getdents64.S:9
    #01 pc 000000000001e36c /system/lib64/libc.so __fill_DIR(DIR*) 于 dirent.cpp:96 (discriminator 1)
    (已内连入) __readdir_locked(DIR*) 于 dirent.cpp:106 (discriminator 1)
    (已内连入) readdir 于 dirent.cpp:121 (discriminator 1)
    #02 pc 0000000000004d80 /system/bin/sdcard find_file_within 于 sdcard.c:391
    #03 pc 00000000000037f8 /system/bin/sdcard handle_lookup 于 sdcard.c:811 (discriminator 1)
    (已内连入) handle_fuse_request 于 sdcard.c:1703 (discriminator 1)
    (已内连入) handle_fuse_requests 于 sdcard.c:1854 (discriminator 1)
    (已内连入) start_handler 于 sdcard.c:1871 (discriminator 1)
    #04 pc 0000000000068618 /system/lib64/libc.so __pthread_start(void*) 于 pthread_create.cpp:198 (discriminator 1)
    #05 pc 000000000001df68 /system/lib64/libc.so __start_thread 于 clone.cpp:41 (discriminator 1)
    "sdcard" sysTid=25872
    #00 pc 000000000006b4f0 /system/lib64/libc.so read 于 read.S:7
    #01 pc 0000000000002fd8 /system/bin/sdcard read 于 unistd.h:465
    (已内连入) handle_fuse_requests 于 sdcard.c:1828
    (已内连入) start_handler 于 sdcard.c:1871
    #02 pc 0000000000068618 /system/lib64/libc.so __pthread_start(void*) 于 pthread_create.cpp:198 (discriminator 1)
    #03 pc 000000000001df68 /system/lib64/libc.so __start_thread 于 clone.cpp:41 (discriminator 1)
    "sdcard" sysTid=25873
    #00 pc 000000000006b4f0 /system/lib64/libc.so read 于 read.S:7
    #01 pc 0000000000002fd8 /system/bin/sdcard read 于 unistd.h:465
    (已内连入) handle_fuse_requests 于 sdcard.c:1828
    (已内连入) start_handler 于 sdcard.c:1871
    #02 pc 0000000000068618 /system/lib64/libc.so __pthread_start(void*) 于 pthread_create.cpp:198 (discriminator 1)
    #03 pc 000000000001df68 /system/lib64/libc.so __start_thread 于 clone.cpp:41 (discriminator 1)
    ----- end 25870 ----- 
    

    查看sdcard源码

    路径system/core/sdcard/sdcard.c
    对应于解析后的文件,找到find_file_within的函数

            while ((entry = readdir(dir))) {
                if (!strcasecmp(entry->d_name, name)) {
                    /* we have a match - replace the name, don't need to copy the null again */
                    memcpy(actual, entry->d_name, namelen);
                    break;
                }
            }
            closedir(dir);
    

    发现最后是在readdir文件中,这个需要看kernel中的情况啦。

    分析kernel文件

    后面就是根据这个trace文件继续看代码啦,和sdcard的情况类似,这里就不详说啦。

    后记

    本文就是记录利用addr2line分析anr的一种思路。 anr的出现有各种情况,基本上要case by case的看。但是思路都差不多,就是利用android log和trace文件结合着看。如果是必现的情况则也可以通过增加log复现然后解决问题,如果是偶现的则只能通过log和代码的蛛丝马迹来推测啦。

    相关文章

      网友评论

          本文标题:Android利用addr2line分析traces.txt

          本文链接:https://www.haomeiwen.com/subject/esjifxtx.html