android 中anr的分析方法总结

在android开发过程中,总会容易遇到各种anr(Application Not Responding),今天测试同事发现一个bug,在连接wifi后,回到桌面,提示启动器无响应,并黑屏。于是分析了下日志:

    1、首先找到对应的trace.txt文件或者anr文件。

     我们公司的anr日志信息主要在anr/trace.txt和dropbox/文件夹下,通过dropbox/[email protected],搜索:Cmd line:

   

Cmd line: com.**.android.launcher3
Cmd line: system_server
    发现有对应的launcher和system_server的anr,分别看日志,可以初步判断,是由于system_server出现anr导致了launcher的anr。


2、找到出现anr的进程后,首先查看主线程,其日志入下。可以看出,主线程是0x097ca713 这个锁被其他线程给拿锁了,且是被线程号为53的线程拿住。(在线程后面,tid即为线程号)


   

"main" prio=5 tid=1 Blocked
  | group="main" sCount=1 dsCount=0 obj=0x74f26cc8 self=0x7f7ba96a00
  | sysTid=1759 nice=-2 cgrp=default sched=0/0 handle=0x7f8004ba98
  | state=S schedstat=( 6861267460 2526571997 15724 ) utm=491 stm=195 core=6 HZ=100
  | stack=0x7fd14ba000-0x7fd14bc000 stackSize=8MB
  | held mutexes=
  at com.android.server.net.NetworkPolicyManagerService.isNetworkMetered(NetworkPolicyManagerService.java:2342)
  - waiting to lock <0x097ca713> (a java.lang.Object) held by thread 53
  at com.android.server.ConnectivityService.filterNetworkStateForUid(ConnectivityService.java:1121)
  at com.android.server.ConnectivityService.getFilteredNetworkState(ConnectivityService.java:974)
  at com.android.server.ConnectivityService.getNetworkInfo(ConnectivityService.java:1209)
  at android.net.ConnectivityManager.getNetworkInfo(ConnectivityManager.java:905)
  at com.qiku.android.server.aps.s.onReceive(:-1)
  at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:1153)
  at android.os.Handler.handleCallback(Handler.java:751)
  at android.os.Handler.dispatchMessage(Handler.java:95)
  at android.os.Looper.loop(Looper.java:154)
  at com.android.server.SystemServer.run(SystemServer.java:389)
  at com.android.server.SystemServer.main(SystemServer.java:238)
  at java.lang.reflect.Method.invoke!(Native method)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:907)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:797)
搜索tid=53,可以得到如下日志,真是这里拿锁着资源 0x097ca713

原来是手机刚连接wifi时,进行了时间更新(ntp)出现问题,导致一直拿锁资源。

"NetworkPolicy" prio=5 tid=53 Native
  | group="main" sCount=1 dsCount=0 obj=0x13a4aee0 self=0x7f117faa00
  | sysTid=2457 nice=0 cgrp=default sched=0/0 handle=0x7caaf87450
  | state=S schedstat=( 376137393 286800997 1704 ) utm=27 stm=10 core=6 HZ=100
  | stack=0x7caae85000-0x7caae87000 stackSize=1037KB
  | held mutexes=
  kernel: (couldn't read /proc/self/task/2457/stack)
  native: #00 pc 0000000000079190  /system/lib64/libc.so (read+4)
  native: #01 pc 00000000000818f4  /system/lib64/libc.so (__sread+48)
  native: #02 pc 0000000000086154  /system/lib64/libc.so (__srefill+280)
  native: #03 pc 0000000000085f94  /system/lib64/libc.so (fread+272)
  native: #04 pc 0000000000032358  /system/lib64/libc.so (android_getaddrinfofornetcontext+2448)
  native: #05 pc 00000000000319a4  /system/lib64/libc.so (android_getaddrinfofornet+56)
  native: #06 pc 000000000002a710  /system/lib64/libjavacore.so (???)
  native: #07 pc 00000000002bd2f0  /system/framework/arm64/boot-core-libart.oat (Java_libcore_io_Posix_android_1getaddrinfo__Ljava_lang_String_2Landroid_system_StructAddrinfo_2I+188)
  at libcore.io.Posix.android_getaddrinfo(Native method)
  at libcore.io.ForwardingOs.android_getaddrinfo(ForwardingOs.java:55)
  at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:106)
  at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:74)
  at java.net.InetAddress.getByName(InetAddress.java:708)
  at android.net.SntpClient.requestTime(SntpClient.java:89)
  at android.util.NtpTrustedTime.forceRefresh(NtpTrustedTime.java:131)
  at com.android.server.net.NetworkPolicyManagerService.maybeRefreshTrustedTime(NetworkPolicyManagerService.java:3630)
  at com.android.server.net.NetworkPolicyManagerService.setNetworkPolicies(NetworkPolicyManagerService.java:1939)
  at com.android.server.net.NetworkPolicyManagerService.addNetworkPolicyNL(NetworkPolicyManagerService.java:1957)
  at com.android.server.net.NetworkPolicyManagerService$11.onReceive(NetworkPolicyManagerService.java:929)
  - locked <0x097ca713> (a java.lang.Object)
  at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:1153)
  at android.os.Handler.handleCallback(Handler.java:751)
  at android.os.Handler.dispatchMessage(Handler.java:95)
  at android.os.Looper.loop(Looper.java:154)
  at android.os.HandlerThread.run(HandlerThread.java:61)

那么,到底是哪个锁被拿住了,导致了anr呢?从主线程看,是 NetworkPolicyManagerService.isNetworkMetered(NetworkPolicyManagerService.java:2342)

  @Override
    public boolean isNetworkMetered(NetworkState state) {
        if (state.networkInfo == null) {
            return false;
        }

        final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state);

        final NetworkPolicy policy;
        synchronized (mNetworkPoliciesSecondLock) {
            policy = findPolicyForNetworkNL(ident);
        }

        if (policy != null) {
            return policy.metered;
        } else {
            final int type = state.networkInfo.getType();
            if ((isNetworkTypeMobile(type) && ident.getMetered()) || type == TYPE_WIMAX) {
                return true;
            }
            return false;
        }
    


从代码中个,可以看到,应该是mNetworkPoliciesSecondLock被拿住了。在和ntp相关的地方,同样适用了mNetworkPoliciesSecondLock,因此就刚好对上了

@Override
    public void setNetworkPolicies(NetworkPolicy[] policies) {
        mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);

        final long token = Binder.clearCallingIdentity();
        try {
            maybeRefreshTrustedTime();
            synchronized (mUidRulesFirstLock) {
                synchronized (mNetworkPoliciesSecondLock) {
                    normalizePoliciesNL(policies);
                    updateNetworkEnabledNL();
                    updateNetworkRulesNL();
                    updateNotificationsNL();
                    writePolicyAL();
                }
            }
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }


你可能感兴趣的:(android 中anr的分析方法总结)