Android trace文件分析小技巧

Android anr trace文件分析小技巧

网上有很多trace文件分析博客,但是都是解释anr发生得原因,没有指导anr文件如何着手分析?本篇文章就是讲trace文件怎么切入?

trace文件中得异常可能

和网上其它博客一样,先讲讲异常发生得可能,哪些异常会被捕获到trace文件,可能是争抢锁lock、耗时等待、内存资源不足等等,具体可以看链接ANR日志分析全面解析

trace文件分析

不同版本可能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文件,相信大家看了上面的案例已经学会如何分析了

猜你喜欢

转载自blog.csdn.net/jackzhouyu/article/details/127487742