移动性能测试 Monkey+Logcat+traces 查找以及分析定位 ANR 问题 (四)

金主 · March 08, 2018 · Last by 戴小红帽的大灰狼 replied at June 27, 2018 · 4458 hits
:文章有说的不对的地方,大家可以帮忙指出!
Monkey 测试基本操作介绍(一)
Monkey 测试日志讲解(二)
Monkey+Logcat+DDMS内存泄漏分析以及定位(三)
Monkey+Logcat+traces 查找以及分析定位 ANR 问题(四)
Monkey+battery-historian 电量测试(五)

adb logcat作用:

把设备上的操作实时打印出来,比如app崩溃/异常,显示崩溃的原因,如空指针、参数错误、下标越界等。

操作步骤

  • 打开窗口1,执行:adb logcat 获取log,如果要保存文件,加上> /路径/新建后缀为.log的文件
  • 结合monkey操作,重新打开窗口2,执行monkey命令
  • monkey测试执行结束时,立刻在窗口1上输入快捷键ctrl+c

logcat日志详细解析

  1. --------- beginning of xxxx

    1. 解析:日志以--------- beginning of xxxx为起点,开始捕捉Android日志。xxx对应这存储着Android日志记录器的环形缓冲区。Android系统在运行时会时刻在几个设备文件中的一个中写入字符串。而这几个设备文件指向几个环形缓冲区。这是Android日志的记录原理。而这几个缓冲区合称日志记录器缓冲区。
    2. 扩展,讲讲logcat缓冲区log。
      logcat缓冲区介绍: android log输出量巨大,特别是通信系统的log, 缓冲区主要给系统组件使用,一般的应用不需要关心,应用的log都输出到main缓冲区中 .
      1. Radio:无线电,无线网络设备/电话通讯相关log

      2. System:系统,系统组件或系统应用的log

      3. Event:事件,事件/监听相关log

      4. Main:主要,所有java层的log,遗迹不属于上面3层的log

      5. Crash:崩溃,应用崩溃时在此写入崩溃信息log

      注意:使用命令adb logcat -b default时(显示默认的缓冲区log),未特殊指定缓冲区名称,指main,system,crash缓冲区的log。

  2. 如图:

    1. 02-10 10:13:14.234 21857 18515 E AndroidRuntime: FATAL EXCEPTION: URGENT_THREAD_540
      我给大家大概翻译下:

      1. 日志时间:02-10 10:13:14.234

      2. PID(进程ID):21857

      3. TID(线程ID):18515

      4. 优先级:E

      5. 便签:AndroidRuntime

      6. 正文日志:FATAL EXCEPTION: URGENT_THREAD_540

    2. 现在我再针对这句话给大家进行详细的说明(不带任何参数的logcat命令):
      默认输出的日志格式:(不带任何参数的logcat命令)
      由六部分组成:

      1. 写下日志时的时间,如上中07-22 20:31:21.565。

      2. PID(进程ID),如上中993。

      3. TID(线程ID),如上中1032。

      4. 优先级,在Android中,日志的优先级从低到高分以下几种:
      ☀ V—Verbose(啰嗦,最低级别,开发调试中的一些详细信息,仅在开发中使用,不可在发布产品中输出,不是很常见,包含诸如方法名,变量值之类的信息)

      ☀ D—Debug(调试,用于调试的信息,可以在发布产品中关闭,比较常见,开发中经常选择输出此种级别的日志,有时在beta版应用中出现)

      ☀ I—Info(信息,该等级日志显示运行状态信息,可在产品出现问题时提供帮助,从该级别开始的日志通常包含完整意义的英语语句和调试信息,是最常见的日志级别)

      ☀ W—Warning(警告,运行出现异常即将发生错误或表明已发生非致命性错误,该级别日志通常显示出执行过程中的意外情况,例如将try-catch语句块中的异常打印堆栈轨迹之后可输出此种级别日志)

      ☀ E—Error(错误,已经出现可影响运行的错误,比如应用crash时输出的日志)

      ☀ F—Fatal(严重错误,比error级别更高,目前我只在android系统内核发出的日志中看到此种级别。在Android6.0以前表明开发者认为绝对不应该出现的错误,在此以后一般开发场景下绝不应该输出此种级别的日志)

      ☀ S—Silent(寂静,最高级别,没有一条日志会属于这个级别,仅仅作为关闭logcat输出的过滤器参数)
      示例中日志等级显示为W,表示警告级别。

      5. 标签,标明日志发起者和方便日志的过滤筛选,如上中BroadcastQueue,表示该日志关于广播队列。

      6. 正文,本日志的主体内容。示例日志中表示一个后台执行被阻止,并显示出了接收到的意图的详细信息。

参考链接:https://www.ithome.com/html/android/318639.htm

从logcat.log中发现内存泄漏方法(上节遗留)

  1. 在logcat.log中搜索关键词GC,如果有下面四个中的一个,就可能存在内存泄露。

    1. GC_FOR_ALLOC, 因为在分配内存时内存丌够引发的
    2. GC_EXPLICIT, 表明GC被显式请求触发的,如System.gc调用
    3. GC_CONCURRENT, 表明GC在内存使用率达到一定的警戒值时,自动触发。
    4. GC_BEFORE_OOM, 表明在虚拟机抛出内存丌够异常OOM之前,执行最后一次回收内存垃圾

    举例:

    02-27 14:42:52.544 I/art     ( 1844): Background sticky concurrent mark sweep GC freed 181925(7MB) AllocSpace objects, 0(0B) LOS      objects, 9% free, 74MB/82MB, paused 2.857ms total 104.330ms

    解析:Gson序列化问题导致的内存溢出,问题原因,如果在json model里面放了非可序列化的对象就会导致这中问题,可序列化的就是那些基础数据类型和集合类型,如果在里面放个Android的Activity或者adapter这类类型字段,变量声明前面一定要加

    transient,否则就是长期GC提示。

从logcat.log中查找ANR以及ForceClosed 等异常退出问题

  1. 如果是ANR问题 , 则搜索“ANR ”关键词(ANR后加个空格,屏蔽掉anr.log文件的无效信息) 。 快速定位到关键事件信息 。
  2. 如果是ForceClosed 和其它异常退出信息,则搜索"Fatal" 关键词, 快速定位到关键事件信息 。
  3. 定位到关键事件信息后 , 如果信息不够明确的,再去搜索应用程序包的虚拟机信息 ,查看具体的进程和线程跟踪的日志,来定位到代码 。

traces日志中ANR的定位与分析

  1. 当ANR发生时除过logcat可以看见的log以外,我们还可以在系统指定目录下找到traces文件进行分析,获取ANR trace文件: adb pull /data/anr/traces.txt /Users/weixiangyang/Desktop/
  2. 分析虚拟机信息,搜索Dalvik Thread关键词,快速定位到本应用程序的虚拟机信息日志,如下:
//显示进程id、ANR发生时间点、ANR发生进程包名
----- pid 8562 at 2018-03-03 14:39:49 -----
Cmd line: com.taobao.taobao
//一些GC等object信息,通常可以忽略
......
//ANR方法堆栈打印信息!重点!
DALVIK THREADS (132):
"main" prio=5 tid=1 Native
| group="main" sCount=1 dsCount=0 obj=0x787c5000 self=0x7f8e696a00
| sysTid=1786 nice=-10 cgrp=default sched=0/0 handle=0x7f92c45aa0
| state=S schedstat=( 0 0 0 ) utm=17421 stm=10643 core=4 HZ=100
| stack=0x7fcaf1e000-0x7fcaf20000 stackSize=8MB
| held mutexes=
kernel: (couldn't read /proc/self/task/1786/stack)
native: #00 pc 0000000000078230 /system/lib64/libc.so (__epoll_pwait+8)
native: #01 pc 000000000001e80c /system/lib64/libc.so (epoll_pwait+64)
native: #02 pc 00000000000185c0 /system/lib64/libutils.so (_ZN7android6Looper9pollInnerEi+160)
native: #03 pc 0000000000018460 /system/lib64/libutils.so (_ZN7android6Looper8pollOnceEiPiS1_PPv+60)
native: #04 pc 00000000000f2d24 /system/lib64/libandroid_runtime.so (_ZN7android18NativeMessageQueue8pollOnceEP7_JNIEnvP8_jobjecti+48)
native: #05 pc 0000000000b790b0 /system/framework/arm64/boot-framework.oat (Java_android_os_MessageQueue_nativePollOnce__JI+140)
//真正导致ANR的问题点
at android.os.MessageQueue.nativePollOnce(Native method)
at android.os.MessageQueue.next(MessageQueue.java:323)
at android.os.Looper.loop(Looper.java:142)
at com.android.server.SystemServer.run(SystemServer.java:377)
at com.android.server.SystemServer.main(SystemServer.java:239)
at java.lang.reflect.Method.invoke!(Native method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:901)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:791)
......
//省略一些不常关注堆栈打印

每一段都是一个线程 。通过分析发现关键问题,到这里就可以找开发协助,深入代码具体分析,将 traces日志,logcat有问题的日志进行整理,发给开发即可!

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 7 条回复 时间 点赞
金主 Monkey 测试日志讲解 (二) 中提及了此贴 08 Mar 17:12
金主 Monkey 测试基本操作介绍 (一) 中提及了此贴 08 Mar 17:12

赞下,来WIKI里建个系列文章吧,https://testerhome.com/wiki/new

金主 Mac 下如何安装 MySQL 中提及了此贴 09 Mar 12:10

jinzhu 我之前都是做的web和后端服务的一些测试,现在想转 学习一些APP方面的测试知识,该学习哪些 从哪些开始啊

金主 Monkey+battery-historian 电量测试 (五) 中提及了此贴 09 Mar 16:33
金主 #8 · March 12, 2018 作者
Wan 回复

不是这块的大佬,不敢瞎指定

金主 #9 · March 12, 2018 作者
国文 回复

咋整?不会😭

Author only
金主 #11 · March 12, 2018 作者
国文 回复

感谢

Author only
simple 专栏文章:[精华帖] 社区历年精华帖分类归总 中提及了此贴 13 Dec 14:44
需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up