android ANR异常定位分析
一. 问题定位
1. 发生anr异常 会在data/anr目录下 存在异常记录
微信图片_20230328095414.png 微信图片_20230328095420.png使用adb pull data/anr 因为没有权限 会获取失败 更换命令 使用adb bugreport 打包anr信息
成功后 会告知存放位置。解压后文件目录:
1679968766837.png
文件夹中两处 都有相关错误信息
(1)FS/data/anr下 这个更好定位
(2)bugreport-PEXMOO-...文件
定位问题(1)
打开文件大致内容
cmd line 确认是当前应用包名 Cmd line: com.test.test
----- pid 27325 at 2023-03-24 14:36:23 -----
Cmd line: com.test.test
Build fingerprint: 'Xiaomi/renoir/renoir:11/RKQ1.201112.002/V12.5.8.0.RKICNXM:user/release-keys'
ABI: 'arm64'
Build type: optimized
Zygote loaded classes=21457 post zygote classes=1841
Dumping registered class loaders
#0 dalvik.system.PathClassLoader: [], parent #1
#1 java.lang.BootClassLoader: [], no parent
#2 dalvik.system.PathClassLoader: [/system/framework/tcmclient.jar], parent #0
#3 dalvik.system.PathClassLoader: [], parent #0
全局搜 "main" prio=5 确认问题点
"main" prio=5 tid=1 Blocked
| group="main" sCount=1 dsCount=0 flags=1 obj=0x72c36338 self=0xb400006fa7094c00
| sysTid=27325 nice=-10 cgrp=top-app sched=0/0 handle=0x702e4cc4f8
| state=S schedstat=( 168352756660 13839364110 211677 ) utm=14483 stm=2351 core=5 HZ=100
| stack=0x7fd4b47000-0x7fd4b49000 stackSize=8192KB
| held mutexes=
at android.os.MessageQueue.enqueueMessage(MessageQueue.java:557)
- waiting to lock <0x03180f01> (a android.os.MessageQueue)
at android.os.Handler.enqueueMessage(Handler.java:778)
at android.os.Handler.sendMessageAtTime(Handler.java:727)
at android.view.ViewRootImpl$ViewRootHandler.sendMessageAtTime(ViewRootImpl.java:5135)
at android.os.Handler.sendMessageDelayed(Handler.java:697)
at android.os.Handler.postDelayed(Handler.java:499)
at android.view.HandlerActionQueue.executeActions(HandlerActionQueue.java:85)
- locked <0x0196e1a6> (a android.view.HandlerActionQueue)
at android.view.View.dispatchAttachedToWindow(View.java:20667)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3522)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3529)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3529)
at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:3529)
... repeated 2 times
at android.view.ViewGroup.addViewInner(ViewGroup.java:5316)
at android.view.ViewGroup.addView(ViewGroup.java:5102)
at android.view.ViewGroup.addView(ViewGroup.java:5039)
at androidx.recyclerview.widget.RecyclerView$5.addView(RecyclerView.java:889)
at androidx.recyclerview.widget.ChildHelper.addView(ChildHelper.java:107)
at androidx.recyclerview.widget.RecyclerView$LayoutManager.addViewInt(RecyclerView.java:8902)
at androidx.recyclerview.widget.RecyclerView$LayoutManager.addView(RecyclerView.java:8860)
at androidx.recyclerview.widget.RecyclerView$LayoutManager.addView(RecyclerView.java:8848)
at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1645)
at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1591)
at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:668)
at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4309)
at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:4012)
at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4578)
at android.view.View.layout(View.java:23125)
at android.view.ViewGroup.layout(ViewGroup.java:6460)
at androidx.viewpager2.widget.ViewPager2.onLayout(ViewPager2.java:527)
at android.view.View.layout(View.java:23125)
at android.view.ViewGroup.layout(ViewGroup.java:6460)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1103)
at android.view.View.layout(View.java:23125)
at android.view.ViewGroup.layout(ViewGroup.java:6460)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
at android.view.View.layout(View.java:23125)
at android.view.ViewGroup.layout(ViewGroup.java:6460)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1829)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1673)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1582)
at android.view.View.layout(View.java:23125)
at android.view.ViewGroup.layout(ViewGroup.java:6460)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
at android.view.View.layout(View.java:23125)
at android.view.ViewGroup.layout(ViewGroup.java:6460)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1829)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1673)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1582)
at android.view.View.layout(View.java:23125)
at android.view.ViewGroup.layout(ViewGroup.java:6460)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
at com.android.internal.policy.DecorView.onLayout(DecorView.java:797)
at android.view.View.layout(View.java:23125)
at android.view.ViewGroup.layout(ViewGroup.java:6460)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:3626)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3085)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2075)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8522)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1077)
at android.view.Choreographer.doCallbacks(Choreographer.java:897)
at android.view.Choreographer.doFrame(Choreographer.java:826)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1062)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:233)
at android.app.ActivityThread.main(ActivityThread.java:8052)
at java.lang.reflect.Method.invoke(Native method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:656)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)
"main" prio=5 tid=1 Blocked
mian:主线程
prio =5: 线程优先级
Blocked: 当前线程状态 表示当前主线程阻塞 ANR
(线程的状态:
NEW - 创建状态
RUNNABLE - 就绪或运行状态
BLOCKED - 阻塞状态
WATING - 等待状态
TIMED_WAITING - 定时等待状态
TERMINATED - 终止状态)
继续问题定位 当前信息没有自己代码的问题 都是系统代码 但是代码中有两处lock
- waiting to lock <0x03180f01> (a android.os.MessageQueue)
- locked <0x0196e1a6> (a android.view.HandlerActionQueue)
根据地址 搜索调用位置 0x03180f01
"Timer-19" prio=5 tid=123 Runnable
| group="main" sCount=0 dsCount=0 flags=0 obj=0x14b07060 self=0x6f8a648c00
| sysTid=6393 nice=0 cgrp=top-app sched=0/0 handle=0x6f25357cc0
| state=R schedstat=( 70680442813 8390554181 396852 ) utm=6118 stm=949 core=7 HZ=100
| stack=0x6f25254000-0x6f25256000 stackSize=1043KB
| held mutexes= "mutator lock"(shared held)
at android.os.MessageQueue.enqueueMessage(MessageQueue.java:586)
- locked <0x03180f01> (a android.os.MessageQueue)
at android.os.Handler.enqueueMessage(Handler.java:778)
at android.os.Handler.sendMessageAtTime(Handler.java:727)
at android.view.ViewRootImpl$ViewRootHandler.sendMessageAtTime(ViewRootImpl.java:5135)
at android.os.Handler.sendMessageDelayed(Handler.java:697)
at android.os.Handler.post(Handler.java:427)
at android.view.View.post(View.java:18950)
at com.xxx.xxxx.webView.BaseWebViewClient$TT.run(BaseWebViewClient.kt:23)
at java.util.TimerThread.mainLoop(Timer.java:562)
at java.util.TimerThread.run(Timer.java:512)
然后发现在自己代码中的问题点
at com.xxx.xxxx.webView.BaseWebViewClient$TT.run(BaseWebViewClient.kt:23)
定位问题(2)
打开文件大概信息
========================================================
== dumpstate: 2023-03-24 15:17:39
========================================================
Build: RKQ1.201112.002 test-keys
Build fingerprint: 'Xiaomi/renoir/renoir:11/RKQ1.201112.002/V12.5.8.0.RKICNXM:user/release-keys'
Bootloader: unknown
Radio: 4.0-c7-11.1873.2-1026_2256_b83f4dadbc,4.0-c7-11.1873.2-1026_2256_b83f4dadbc
Network: ,
Module Metadata version: 30
Kernel: Linux version 5.4.86-qgki-g481f7eca2ed5 (builder@m1-xm-ota-bd044.bj.idc.xiaomi.com) (Android (6443078 based on r383902) clang version 11.0.1 (https://android.googlesource.com/toolchain/llvm-project b397f81060ce6d701042b782172ed13bee898b79), LLD 11.0.1 (/buildbot/tmp/tmp6_m7QH b397f81060ce6d701042b782172ed13bee898b79)) #1 SMP PREEMPT Wed Oct 27 15:02:49 CST 2021
Command line: ramoops_memreserve=4M log_buf_len=256K rcupdate.rcu_expedited=1 rcu_nocbs=0-7 console=ttyMSM0,115200n8 androidboot.hardware=qcom androidboot.console=ttyMSM0 androidboot.memcg=1 lpm_levels.sleep_disabled=1 video=vfb:640x400,bpp=32,memsize=3072000 msm_rtb.filter=0x237 service_locator.enable=1 androidboot.usbcontroller=a600000.dwc3 swiotlb=0 loop.max_part=7 cgroup.memory=nokmem,nosocket pcie_ports=compat loop.max_part=7 iptable_raw.raw_before_defrag=1 ip6table_raw.raw_before_defrag=1 buildvariant=user androidboot.verifiedbootstate=green androidboot.keymaster=1 androidboot.vbmeta.device=PARTUUID=65cc4597-
搜索关键字 VM TRACES AT LAST ANR 确认当前包名 Cmd line: com.test.test
------ 0.007s was the duration of 'VM TRACES JUST NOW' ------
------ VM TRACES AT LAST ANR (/data/anr/anr_2023-03-24-14-36-34-749: 2023-03-24 14:36:42) ------
----- pid 27325 at 2023-03-24 14:36:35 -----
Cmd line: com.test.test
Build fingerprint: 'Xiaomi/renoir/renoir:11/RKQ1.201112.002/V12.5.8.0.RKICNXM:user/release-keys'
ABI: 'arm64'
Build type: optimized
Zygote loaded classes=21457 post zygote classes=1862
后面的步骤和(1)一致
2. 集成了bugly之类第三方异常捕捉上报工具,这里会有详细的信息 定位方式如上
1679974685314(1).png三. 问题发生原因
ANR(Application Not Responding) 应用程序无响应。如果你应用程序在UI线程被阻塞太长时间,就会出现ANR,通常出现ANR,系统会弹出一个提示提示框,让用户知道,该程序正在被阻塞,是否继续等待还是关闭。
ANR类型
出现ANR的一般有以下几种类型:
1:KeyDispatchTimeout(常见)
input事件在5S内没有处理完成发生了ANR。
logcat日志关键字:Input event dispatching timed out
2:BroadcastTimeout
前台Broadcast:onReceiver在10S内没有处理完成发生ANR。
后台Broadcast:onReceiver在60s内没有处理完成发生ANR。
logcat日志关键字:Timeout of broadcast BroadcastRecord
3:ServiceTimeout
前台Service:onCreate,onStart,onBind等生命周期在20s内没有处理完成发生ANR。
后台Service:onCreate,onStart,onBind等生命周期在200s内没有处理完成发生ANR
logcat日志关键字:Timeout executing service
4:ContentProviderTimeout
ContentProvider 在10S内没有处理完成发生ANR。
logcat日志关键字:timeout publishing content providers
ANR出现常见原因
1:主线程频繁进行耗时的IO操作:如数据库读写
2:多线程操作的死锁,主线程被block;
3:主线程被Binder 对端block;
4:System Server中WatchDog出现ANR;
5:service binder的连接达到上线无法和和System Server通信
6:系统资源已耗尽(管道、CPU、IO)
https://juejin.cn/post/6844903942841712648
https://juejin.cn/post/6844903715313303565#heading-4