崩溃信息
-
崩溃信息
- 进程名,线程名:确认崩溃的进程是前台进程还是后台进程,崩溃是不是发生在UI线程
- 崩溃的堆栈类型:Java崩溃,Native崩溃,ANR,要注意崩溃发生在自己的代码还是系统的代码中
-
系统信息
- Logcat: 包括应用、系统运行日志,机型、系统、厂商、CPU、ABI、Linux版本等,会采集多达十几个维度的信息
- 设备状态:是否 root、是否是模拟器。一些问题是由 Xposed 或多开软件造成,对这部 分问题我们要区别对待
-
内存信息
- OOM、ANR、虚拟内存耗尽
- 系统剩余内存:关于系统内存状态,可以直接读取文件 /proc/meminfo。当系统可用 内存很小(低于 MemTotal 的 10%)时,OOM、大量 GC、系统频繁自杀拉起等问题 都非常容易出现
- 应用使用内存:包括 Java 内存、RSS(Resident Set Size)、PSS(Proportional Set Size),我们可以得出应用本身内存的占用大小和分布。PSS 和 RSS 通过 /proc/self/smap 计算,可以进一步得到例如 apk、dex、so 等更加详细的分类统计
- 虚拟内存:虚拟内存可以通过 /proc/self/status 得到,通过 /proc/self/maps 文件可 以得到具体的分布情况。有时候我们一般不太重视虚拟内存,但是很多类似 OOM、 tgkill 等问题都是虚拟内存不足导致的
-
资源信息
-
有的时候发现应用堆内存和设备内存都非常充足,还是会出现内存分配失败的情况,这跟资源泄漏可能有比较大的关系
- 文件句柄 fd:文件句柄的限制可以通过 /proc/self/limits 获得,一般单个进程允许打开的最大文件句柄个数为 1024。但是如果文件句柄超过 800 个就比较危险,需要将所有的 fd 以及对应的文件名输出到日志中,进一步排查是否出现了有文件或者线程的泄漏
- 线程数:当前线程数大小可以通过上面的 status 文件得到,一个线程可能就占 2MB 的 虚拟内存,过多的线程会对虚拟内存和文件句柄带来压力。如果线程数超过 400 个就比较危险。需要将所有的线程 id 以及对应的线程名输出到日志中, 进一步排查是否出现了线程相关的问题
- JNI:使用 JNI 时,如果不注意很容易出现引用失效、引用爆表等一些崩溃。我们可以 通过 DumpReferenceTables 统计 JNI 的引用表,进一步分析是否出现了 JNI 泄漏等 问题
-
应用信息
- 崩溃场景:崩溃发生在那个Activity或Fragment
- 复现路径:不同于开发过程详细的打点日志,我们可以记录关键的用户操作路径, 这对我们复现崩溃会有比较大的帮助
- 自定义信息:运行时间、是否加载了补丁、是否是全新安装或升级等信息
崩溃分析
- 崩溃基本信息
- 确定崩溃的类型以及异常描述,对崩溃有大致的判断。一般来说,大部分的简单崩溃经过这一步已经可以得到结论
崩溃类型 | 分析方法 |
---|---|
Java崩溃 | Java 崩溃类型比较明显,比如 NullPointerException 是空指针,OutOfMemoryError 是资源不足,这个时候需要去进一步查看日志中的 “内存信 息”和“资源信息” |
Native崩溃 | 需要观察 signal、code、fault addr 等内容,以及崩溃时 Java 的堆栈。 关于各 signal 含义的介绍,你可以查看崩溃信号介绍。比较常见的是有 SIGSEGV 和 SIGABRT,前者一般是由于空指针、非法指针造成,后者主要因为 ANR 和调用 abort() 退出所导致 |
ANR | 先看看主线程的堆栈,是否是因为锁等待导致。接着看看 ANR 日 志中 iowait、CPU、GC、system server 等信息,进一步确定是 I/O 问题,或是 CPU 竞争问题,还是由于大量 GC 导致卡死 |
-
Logcat
- Logcat 一般会存在一些有价值的线索,日志级别是 Warning、Error 的需要 特别注意。从 Logcat 中我们可以看到当时系统的一些行为跟手机的状态,例如出现 ANR 时,会有“am_anr”;App 被杀时,会有“am_kill”。不同的系统、厂商输出的日志有 所差别,当从一条崩溃日志中无法看出问题的原因,或者得不到有用信息时,不要放弃, 建议查看相同崩溃点下的更多崩溃日志
-
各个资源情况
- 结合崩溃的基本信息,可以看看是不是跟资源有关(物理资源不足,虚拟内存不足,或者文件句柄fd泄露)
-
复现问题
- 复现问题是解决问题的最好的方式,可以让我们快速定位问题点,非必现的概率问题是不好解决的,这时候我们需要打印log, 看执行流程
-
查找共性
- 如果上面的方法还是不能有效定位问题,尝试查找这类崩溃有没有什么共性
- 比如某一机型,某一系统版本都有这种问题
注意:
- 对于Monkey跑出来的crash问题,有时候手动是无法复现的,这时候log的关键作用就可以体现,要查看完整的log日志,分析整个应用的执行流程,定位问题点