BugFree三剑客异常、日志、工具

BugFree三剑客异常、日志、工具—Android开发排查问题小结#

前言#

程序员编写程序、调试代码的时候不可避免的会遇到各种问题,如页面显示不正确,如数据层数据组装操作未按照期望的业务逻辑执行。

造成这些问题的原因大多分为以下几种:有些是条件语句执行错误,有些是Java层的Exception如空指针、集合边界越界问题,有些是较难找到原因的OOM、ANR、Crash、系统SWT重启问题。面对扑面而来的问题,程序员很容易束手无策。笔者结合自己的经验,总结了BugFree中必不可少的三剑客:异常、日志、工具,期望通过这3个“帮手”,帮助各位排查开发难题。

参考阅读#

Mtk Log使用指南

异常#

异常的分类#

Android是一个庞大而复杂的系统,涉及多种语言,所以其异常也很复杂。根据android系统架构层次,我们也把android异常层次化,分为JE、NE、KE、EE、其他类别

w w
JE
(Java layer exception)
一般是在应用层和框架层发生的异常,通常是由Java代码,XML代码引起的。比如各种RuntimeException, ANR(Application Not Responding)、SWT(Software Watchdog Timeout)等
NE
(Native layer exception)
发生在Linux用户空间的异常,通常是由C/C++代码和库文件引起的。比如内核发出的NE信号(SIGILL、 SIGABRT、 SIGBUS等)
KE
(Kernel layer execption)
通常指内核故障或内核错误,由于在内核模式下出错,这类异常是非常严重的,往往会导致重启、死机或无法开机等
EE
(External (Modem) exception)
从名字看就能猜到Modem这一部分是比较特殊的,独立的。Modem有自己的内存空间和代码,为手机通讯提供服务,一旦这一部分发生异常,需要MDlog,此log需用AEE-LogVie工具解析,解析是需要对应版本的数据文件

日志#

用途#

搜索关键异常#

1.常见应用crash

(系统提示***已停止运行) 可以在main log中或crash_log中直接搜索“ fatal exception” ;也可以在event_log中搜索am_crash快速定位到问题

关键字 原理
uncaughtException Android 顶级异常捕获
Exception Java 异常基类
NetworkOnMainThreadException 网络异常
ANR Warning ANR TAG
Application Not Response ANR TAG
FATAL 异常 TAG
ANRManager ANR TAG
Log的TAG Log工具类的TAG

2.应用闪退

应用闪退一般有如下三种原因:

1).目前遇到最多的主要是因为low memory killer机制在内存达到一定阈值的时候会将大于对应adj进程给kill掉(这个一般在kernel log中搜索关键字“ low memory kill ”就可以确认哪些是因为lmk机制而被kill);一般此情况下跟性能有关……。

2). 关联进程被kill导致;

kill

一般在进行闪退分析时可以在events log中搜索关键字” am_kill “或者” in dying proc “等

3).应用本身逻辑有执行finish动作而出现,比如点击锁屏通知进入某个对应界面而界面没有出现,这种情况需要分析对应的main_log、event_log;

a:根据出现闪退时间点在event_log搜索am_resume_activity等am_*_activity相关判断这过程中应用是否有启动和退出的动作。

b: 在main_log或sys_log搜索“ACT-AM_”相关信息查看对应activy生命周期相关信息。

其次就根据log跟踪对应代码流程……

搜索OOM#

OOM描述#

Android应用内存管理机制是在Java内存管理机制基础上改进的,所以造成OOM的原因两者差不多,即所有对象都在堆上分配空间,堆是有大小限制的,当分配的对象不能被回收仍然占据堆空间,新分配的对象不能获取足够的堆空间时,就会OOM。为什么会这样呢?这就是GC不足的地方,GC只能回收自己记录(有向树)里面不可达的对象,对可达对象认为是有用的,不会被回收。但是可达对象并非一定是有用对象,他们可能是废弃对象(死对象、冗余对象、电灯泡,僵尸),但却无法被GC回收,占据着进程堆空间,下面是网上的一个对象实例化简图

OOM情景#

资源对象没有回收,如cursor,bitmap等

1通常关闭Cursor的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Cursor cursor = mDownloadManager.query(new Query());

try {

if (cursor.moveToFirst()) {

do {

int index = cursor.getColumnIndex(DownloadManager.COLUMN_ID);

long downloadId = cursor.getLong(index);

ids.add(downloadId);

} while (cursor.moveToNext());

}

} finally {

cursor.close();

}

另外,在adapter中使用cursor时,需在cursor改变的时候先关闭原来的cursor, 但通常我们都是用android提供的CursorAdapter,其changeCursor函数会将原来的Cursor释放掉,并替换为新的Cursor,所以你不用担心原来的Cursor没有被关闭。

2 注册没有对应的去注册,如各种监听

3 生命周期问题引起的无法回收,如果static、线程等

4其他所有发生OOM情景最终都可以认为是对象没有被回收,如,cursor没有close(),bitmap没有recycle(),监听没有unregister…()等等都是因为对象没有被回收,GC认为这些对象是可达的、正在使用的,导致这些应该被回收的对象不能被回收,最终造成OOM。

大多数的回收方法,如close()、recycle()、unregister…(),其实都是把不再使用的对象置为null,这样GC就能回收原来对象所占空间。所以在编程的时候,对全局变量,特别是容器之类的对象和status 修饰对象,要关注其生命周期,不再需要就及时置为null或调用相应的回收方法

OOM的分析思路#

工具准备#

1.log

2.MAT

3.Profiler

4.hprof

复现场景#

1.按log所显示的步骤,多次重复该步骤

2.抓取hrof日志

3.设定怀疑点

4.打印该点的内存大小,如bitmap、集合、集合持有的对象

确认怀疑点#

及时释放掉该对象

OOM分类#

内存泄露

  • Context泄露
  • Handler泄露
  • Cache泄漏
  • 线程未释放导致的泄漏

内存抖动

  • 频繁创建对象

内存溢出

  • 可用内存不足
  • 瞬时申请内存超过了系统可分配内存
  • 大图、长图、宽图
  • 序列过多的图片

OOM优化思路#

这些问题大多是比较难解的问题,大部分都是随机的,往往都是很难复现的,找出规律是很重要的!

另外,内存泄露不容易发现,一些轻微的泄露,可能要使用一个月才能发现,所以对自己的模块,要自己去检查有没有OOM,可以下班时挂上monkey,有时候是能跑出来的

从OOM联想到性能问题,性能问题很多是界面刷新、对象生命周期、冗余操作、不必要的线程等引起的……

搜索SWT#

序号 步骤

具体信息主要查找log文件有sys_log和mtklog\aee_exp\db.fatal.00.SWT\db.fatal.00.SWT.dbg.DEC

搜索死机#

这里说的死机就是冻屏,停留在一个界面没反应。死机问题很少遇到,且大多不是一个用层问题,下面简单说下可能造成死机的原因和分析需要信息

工具准备#

MTK提供了多种抓取和查看LOG的工具, 如:mtklogger,GAT,Catcher,LogView,QAAT等,这些工具在文档《MediaTek_Logging_SOP》中都有描述

mark

Mtklogger*#

Mtklogger是抓取log的apk,整合了ModemLog,MobileLog,NetworkLog and SystemLogger,在工程模式操作就可以打相关log了。

GAT#

基于SDK调试开发的GUI工具,新增了Log Recoder,Debug Configuration Setting,DBpuller,adb command,Process Information view,Profiling Tools,LogView,Plug-in Script。是调试和抓log的神器,使用说明阅读文档《GAT_User_Guide(Customer).pdf》

工具获取路径(以W1444版本为例):

私服SVN:\rd\MTK_TOOL\AndroidTool\W1444\W1444_full.zip\Debugging Tools (Binary)\GAT

Catcher#

是抓取和解析ModemLog的PC端工具,我们经常使用来查看ModemLog,使用说明阅读文档《Catcher_User_Manual_for_Customer.pdf》

工具获取路径:

私服SVN:\rd\MTK_TOOL\AndroidTool\W1444\W1444_full.zip\Catcher

LogView#

可以查看APlog,Taglog,MTKlog,但最常用的是用来查看NE时产生的AEE DB文件里的log,具体使用参考《GAT_User_Guide(Customer).pdf》

工具获取路径:

此工具已集成到GAT

QAAT#

快速分析log的工具,涵盖错误类型较广,很多地方都可以用,其实他的原理就是过滤关键字,把各种类型的错误过滤出来,是一个分析LOG非常便捷的工具,具体使用参考《MediaTek_Logging_SOP.pdf》

死机可能原因:

  1. 输入系统或者输入驱动问题

  2. 系统逻辑问题或阻塞

  3. Surfacefinger问题

  4. 显示系统或LCM驱动问题

相关信息和抓log:

  1. 确认adb是否可用

  2. 抓取bugreport,adb bugreport > d:/bugreport.txt

  3. 抓取dumpstate信息,adb shell dumpstate > d:/dumpstate.txt

  4. 抓取CPU信息,adb shell top –t –m 5 > d:/cpu.txt

  5. 确认是否可以拨打电话,adb shell am start –a android.intent.action.CALL tel:10086(看界面是否能够更新)

  6. 查看按键和触屏报点,adb shell getevent

  7. 抓取Surfacefinger进程信息,先adb shell ps –p找出pid,然后使用adb shell rtt –f bt –p pid > rtt.txt

搜索重启#

从异常分类来看,重启异常大多数和NE、KE和硬件问题有关,JE方面引起重启死机大多是和系统进程有关,如system_process进程发生了Crash、SWT、JVM Error,AP应用一般是不会引起重启死机的,但偶尔也会

72平台上,发送短信内容为‘==’时会重启

虽然是Mms引起的,但最终也是System_process挂掉了,导致重启

重启异常分析步骤(JE):

  1. 确认异常类型(用QAAT跑一下做初步判断,如果是NE、KE让驱动人员帮忙解决)

  2. 找到第一时间发生错误的地方,因为后面的错误多半是因为前面错误引起的,那就没有意义

  3. 根据JE类型,结合对应工具分析LOG

搜索ANR#

ANR定义#

Application Not Responding

ANR种类#

1). Key Dispatch Timeout (8s)

按键或触摸事件在特定时间内无响应(origin:5s)

KEY_DISPATCHING_TIMEOUT = 8*1000

2) .Broadcast Timeout

BroadcastReceiver在特定时间内无法处理完成

BROADCAST_FG_TIMEOUT: 10s

BROADCAST_BG_TIMEOUT: 60s

按键和广播事件时间内未响应,时间限定定义在ActivityManagerService.java类中

3).Service Timeout (20s)——-小概率类型

Service在特定的时间内无法处理完成

service时间内未响应时间限定在ActiveServices.java类中

SERVICE_TIMEOUT = 20*1000;

ANR原因#

1)应用进程有一个主线程(main thread)和一个信息队列(main message queue) main thead == activity thread

2)主线程负责处理像Draw、Listen、receive等UI事件

3)主线程负责从消息队列中取出信息并分发它

4)主线程在完成当前信息处理之前,不会再取信息队列中的信息

5)如果主线程在处理当前信息时卡住,没有及时分发,ANR就会出现

ANR的分析思路#

工具准备#

1 MTKlog,主要是其中的Aee_exp和MobileLog

2Trace.txt文件(data/anr目录下)或者bugreport日志(使用adb bugreport > bugreport.txt或者GAT工具输出)

3BlockCanary,记录超时后的log

4一般当出现异常(JE\SWT\NE\KE等)时,会在手机中的/data/aee_exp目录下保存异常的db。 对于异常的类型和具体信息,需要通过GAT工具解析db档案

5.bugreport

6.aee_exp

Trace分析流程#
序号 步骤
mark
mark
mark
mark
mark
mark
mark
mark

ANR解决方案#

1):UI线程尽量只做跟UI相关的工作

2):耗时的工作(比如数据库操作,I/O,连接网络或者别的有可能阻碍UI线程的操作)把它放入单独的线程处理

3):尽量用Handler来处理UIthread和别的thread之间的交互

ANR优化思路#

优化UI线程的任务:

1):UI线程尽量只做跟UI相关的工作

2):耗时的工作(比如数据库操作,I/O,连接网络或者别的有可能阻碍UI线程的操作)把它放入单独的线程处理

3):尽量用Handler来处理UIthread和别的thread之间的交互

UI线程的主要任务是:

1).Activity:onCreate(), onResume(), onDestroy(), onKeyDown(), onClick()等

2).AsyncTask: onPreExecute(), onProgressUpdate(), onPostExecute(), onCancel等

3).Mainthread handler: handleMessage(), post*(runnable r)等

工具#

工具包名称 用途
联发科MTK组件 MTKLogger
GAT
LogView
QAAT
BlockCanary 开源框架,卡顿日志
Android SDK ADB LogCat
MAT
Android Studio Profile
TraceView

adb#

  1. adb logcat>main.txt 重定向log
  2. adb logcat -b main -v time>app.log 打印应用程序的log
  3. adb logcat -bradio -v time> radio.log 打印射频相关的log,SIM STK 也会在里面,modem相关的ATcommand等。
  4. adb logcat -bevents -v time 打印系统事件的日志,比如触屏事件;
点击查看
-------------------本文结束 感谢您的阅读-------------------