美文网首页
android ANR异常定位分析

android ANR异常定位分析

作者: 微罗妮卡 | 来源:发表于2023-03-27 11:57 被阅读0次

    一. 问题定位

    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

    相关文章

      网友评论

          本文标题:android ANR异常定位分析

          本文链接:https://www.haomeiwen.com/subject/iurihdtx.html