崩溃现场
-
崩溃现场是我们的“第一案发现场”,它保留着很多有价值的线索。在这里我们挖掘到的信息越多,下一步分析的方向就越清晰。
-
操作系统是整个崩溃过程的“旁观者”,也是我们最重要的“证人”,也是我们最重要的“证人”。
-
一个好的崩溃捕获工具知道应该采集哪些系统信息,也知道在什么场景要深入挖掘哪些内容。
1.1 崩溃信息
从崩溃的基本信息,我们可以对崩溃有初步的判断。
- 进程名、线程名。崩溃的进程是前台进程还是后台进程,崩溃是不是发生在 UI 线程。
- 崩溃堆栈和类型。崩溃是属于 Java 崩溃、Native 崩溃,还是 ANR,对于不同类型的崩溃我们关注的点也不太一样。特别需要看崩溃堆栈的栈顶,看具体崩溃在系统的代码,还是我们自己的代码里面。
Process Name: 'com.sample.crash'
Thread Name: 'MyThread'
java.lang.NullPointerException
at ...TestsActivity.crashInJava(TestsActivity.java:275)
1.2 系统信息
Logcat
。这里包括应用、系统的运行日志。由于系统权限问题,获取到的Logcat
可能只包含与当前App
相关的。其中系统的event logcat
会记录App
运行的一些基本情况,记录在文件/system/etc/event-log-tags
中。
system logcat:
10-25 17:13:47.788 21430 21430 D dalvikvm: Trying to load lib ...
event logcat:
10-25 17:13:47.788 21430 21430 I am_on_resume_called: 生命周期
10-25 17:13:47.788 21430 21430 I am_low_memory: 系统内存不足
10-25 17:13:47.788 21430 21430 I am_destroy_activity: 销毁 Activty
10-25 17:13:47.888 21430 21430 I am_anr: ANR 以及原因
10-25 17:13:47.888 21430 21430 I am_kill: APP 被杀以及原因
- 机型、系统、厂商、CPU、ABI、Linux 版本等。–> 寻找共性
- 设备状态:是否 root、是否是模拟器。一些问题是由 Xposed 或多开软件造成,对这部分问题我们要区别对待。
1.3 内存信息
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 等问题都是虚拟内存不足导致的。
opened files count 812:
0 -> /dev/null
1 -> /dev/log/main4
2 -> /dev/binder
3 -> /data/data/com.crash.sample/files/test.config
...
- 线程数。当前线程数大小可以通过上面的
status
文件得到,一个线程可能就占 2MB 的虚拟内存,过多的线程会对虚拟内存和文件句柄带来压力。根据我的经验来说,如果线程数超过 400 个就比较危险。需要将所有的线程id 以及对应的线程名输出到日志中,进一步排查是否出现了线程相关的问题。
threads count 412:
1820 com.sample.crashsdk
1844 ReferenceQueueD
1869 FinalizerDaemon
...
1.4 应用信息
-
崩溃场景。崩溃发生在哪个 Activity 或 Fragment,发生在哪个业务中。
-
关键操作路径。不同于开发过程详细的打点日志,我们可以记录关键的用户操作路径,这对我们复现崩溃会有比较大的帮助。
-
其他自定义信息。不同的应用关心的重点可能不太一样,比如网易云音乐会关注当前播放的音乐,QQ 浏览器会关注当前打开的网址或频。此外例如运行时间、是否加载了补丁、是否是全新安装或升级等信息也非常重要。