在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)
@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);
}
}