赞
踩
网上有很多trace文件分析博客,但是都是解释anr发生得原因,没有指导anr文件如何着手分析?本篇文章就是讲trace文件怎么切入?
和网上其它博客一样,先讲讲异常发生得可能,哪些异常会被捕获到trace文件,可能是争抢锁lock、耗时等待、内存资源不足等等,具体可以看链接ANR日志分析全面解析!
不同版本可能trace文件有所不同,比如Android 10得trace文件没发现由cpu usage等等,也可能是我看漏,重点来了如何查看trace文件中得异常栈:
一般anr都是由main相关线程阻塞引起的,搜索关键字main 的线程看,如下:
"main" prio=5 tid=1 Blocked
| group="main" sCount=1 dsCount=0 flags=1 obj=0x72bcedd8 self=0x72b02aec00
| sysTid=638 nice=-2 cgrp=default sched=0/0 handle=0x72b1810ed0
| state=S schedstat=( 2146765176 863507820 5198 ) utm=169 stm=45 core=2 HZ=100
| stack=0x7ffd09f000-0x7ffd0a1000 stackSize=8192KB
| held mutexes=
at com.android.server.am.ActivityManagerService.broadcastIntent(ActivityManagerService.java:15566)
- waiting to lock <0x0c0b7103> (a com.android.server.am.ActivityManagerService) held by thread 90
at android.app.ContextImpl.sendBroadcastAsUser(ContextImpl.java:1224)
at com.android.server.AlarmManagerService$2.lambda$doAlarm$0$AlarmManagerService$2(AlarmManagerService.java:1546)
at com.android.server.-$$Lambda$AlarmManagerService$2$Eo-D98J-N9R2METkD-12gPs320c.run(lambda:-1)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at com.android.server.SystemServer.run(SystemServer.java:549)
at com.android.server.SystemServer.main(SystemServer.java:351)
at java.lang.reflect.Method.invoke(Native method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:913)
如果出现问题了,main下面就有java的异常栈,我们就可以从这个java异常栈找问题,如果没有java异常栈,说明是没有问题的,那就只有往后一个一个线程tid看,直到有java异常栈就打住,仔细分析;
很明显上面有一句:
waiting to lock <0x0c0b7103> (a com.android.server.am.ActivityManagerService) held by thread 90
main线程在等待lock0x0c0b7103锁,但是这个锁又被90这个线程持有,但是没有释放,那就要看看90这个线程
90线程
"Binder:638_4" prio=5 tid=90 Blocked
| group="main" sCount=1 dsCount=0 flags=1 obj=0x13117ea0 self=0x7175a80000
| sysTid=900 nice=-2 cgrp=default sched=0/0 handle=0x716f22ad50
| state=S schedstat=( 400588157 333711412 1210 ) utm=31 stm=8 core=1 HZ=100
| stack=0x716f134000-0x716f136000 stackSize=991KB
| held mutexes=
at com.android.server.wm.WindowProcessController.setThread(WindowProcessController.java:204)
- waiting to lock <0x0df0d024> (a com.android.server.wm.WindowManagerGlobalLock) held by thread 207
at com.android.server.am.ProcessRecord.makeInactive(ProcessRecord.java:637)
at com.android.server.am.ActivityManagerService.cleanUpApplicationRecordLocked(ActivityManagerService.java:13693)
at com.android.server.am.ActivityManagerService.handleAppDiedLocked(ActivityManagerService.java:3601)
at com.android.server.am.ActivityManagerService.appDiedLocked(ActivityManagerService.java:3753)
at com.android.server.am.ActivityManagerService$AppDeathRecipient.binderDied(ActivityManagerService.java:1504)
- locked <0x0c0b7103> (a com.android.server.am.ActivityManagerService)
at android.os.BinderProxy.sendDeathNotice(BinderProxy.java:620)
很明显,这个90线程需要lock <0x0df0d024>锁,同时持有lock<0x0c0b7103>,但是lock <0x0df0d024>又被207线程持有,没办法,看看207线程。
207线程
"Binder:638_12" prio=5 tid=207 Blocked
| group="main" sCount=1 dsCount=0 flags=1 obj=0x12f806b0 self=0x71778f7000
| sysTid=1758 nice=-4 cgrp=default sched=0/0 handle=0x70e5e54d50
| state=S schedstat=( 437566875 650319463 2262 ) utm=33 stm=10 core=1 HZ=100
| stack=0x70e5d5e000-0x70e5d60000 stackSize=991KB
| held mutexes=
at com.android.server.am.ActivityManagerService.broadcastIntent(ActivityManagerService.java:15566)
- waiting to lock <0x0c0b7103> (a com.android.server.am.ActivityManagerService) held by thread 90
at android.app.ContextImpl.sendBroadcast(ContextImpl.java:1049)
at com.android.server.wm.ActivityRecord.sendBroadcastVREnable(ActivityRecord.java:436)
at com.android.server.wm.ActivityRecord.onWindowsGone(ActivityRecord.java:2458)
at com.android.server.wm.AppWindowToken.onWindowsGone(AppWindowToken.java:457)
at com.android.server.wm.AppWindowToken.updateReportedVisibilityLocked(AppWindowToken.java:444)
at com.android.server.wm.WindowManagerService.postWindowRemoveCleanupLocked(WindowManagerService.java:1838)
at com.android.server.wm.WindowState.removeImmediately(WindowState.java:1925)
at com.android.server.wm.WindowState.removeIfPossible(WindowState.java:2048)
at com.android.server.wm.WindowState.access$300(WindowState.java:216)
at com.android.server.wm.WindowState$DeathRecipient.binderDied(WindowState.java:2498)
- locked <0x0df0d024> (a com.android.server.wm.WindowManagerGlobalLock)
at android.os.BinderProxy.sendDeathNotice(BinderProxy.java:620)
很明显207线程需要lock <0x0c0b7103>,自己持有locked <0x0df0d024>,但是lock <0x0c0b7103>又被90线程持有,这不就是发生死锁了吗?
这不就是我们学习的死锁吗?至于如何解决这种问题,网上很多,不在本文的重点,本文就是教大家如何分析trace文件,相信大家看了上面的案例已经学会如何分析了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。