[Android Pro] analysis of deadlock ANR via Android trace file

Source: Internet
Author: User
Tags high cpu usage

Reprinted from: Http://blog.csdn.net/oujunli/article/details/9102101#reply

For people engaged in Android development, encountering ANR (application not responding) is a more common problem. In general, if there is a ANR occurrence, the system will generate trace files in the/data/anr/directory, by analyzing the trace file, you can locate the cause of the ANR. There are many reasons for the ANR, such as high CPU usage, no timely response to events, deadlocks, and so on, which shows how to analyze the ANR problem through a trace file because of a deadlock-induced ANR problem.

The corresponding section trace file contents are as follows:

"Powermanagerservice" prio=5 tid=24 MONITOR
| group= "main" scount=1 dscount=0 obj=0x41dd0eb0 self=0x5241b218
| systid=567 nice=0 sched=0/0 Cgrp=apps handle=1380038664
| State=s schedstat= (6682116007 11324451214 33313) utm=450 stm=219 core=1
At Com.android.server.am.ActivityManagerService.broadcastIntent (activitymanagerservice.java:~13045)
-Waiting to lock <0x41a874a0> (a Com.android.server.am.ActivityManagerService) held by Tid=12 ( Android.server.ServerThread)
At Android.app.ContextImpl.sendBroadcast (contextimpl.java:1144)
At Com.android.server.power.powermanagerservice$displayblankerimpl.unblankalldisplays (PowerManagerService.java : 3442)
At Com.android.server.power.displaypowerstate$photonicmodulator$1.run (displaypowerstate.java:456)
At Android.os.Handler.handleCallback (handler.java:800)
At Android.os.Handler.dispatchMessage (handler.java:100)
At Android.os.Looper.loop (looper.java:194)
At Android.os.HandlerThread.run (handlerthread.java:60)

"Binder_b" prio=5 tid=85 MONITOR
| group= "main" scount=1 dscount=0 obj=0x42744770 self=0x58329e88
| systid=3700 nice=-20 sched=0/0 Cgrp=apps handle=1471424616
| State=s schedstat= (1663727513 2044643318 6806) utm=132 stm=34 core=1
At Com.android.server.power.powermanagerservice$displayblankerimpl.tostring (powermanagerservice.java:~3449)
-Waiting to lock <0x41a7e420> (a Com.android.server.power.powermanagerservice$displayblankerimpl) held by tid=24 (Powermanagerservice)
At Java.lang.StringBuilder.append (stringbuilder.java:202)
At Com.android.server.power.PowerManagerService.dump (powermanagerservice.java:3052)
At Android.os.Binder.dump (binder.java:264)
At Android.os.Binder.onTransact (binder.java:236)
At Android.os.ipowermanager$stub.ontransact (ipowermanager.java:373)
At Android.os.Binder.execTransact (binder.java:351)
At Dalvik.system.NativeStart.run (Native Method)

"Android.server.ServerThread" prio=5 tid=12 MONITOR
| group= "main" scount=1 dscount=0 obj=0x41a76178 self=0x507837a8
| systid=545 nice=-2 sched=0/0 Cgrp=apps handle=1349936616
| State=s schedstat= (15368096286 21707846934 69485) utm=1226 stm=310 core=0
At Com.android.server.power.PowerManagerService.isScreenOnInternal (powermanagerservice.java:~2529)
-Waiting to lock <0x41a7e2e8> (a Java.lang.Object) held by tid=85 (Binder_b)
At Com.android.server.power.PowerManagerService.isScreenOn (powermanagerservice.java:2522)
At com.android.server.wm.WindowManagerService.sendScreenStatusToClientsLocked (windowmanagerservice.java:7749)
At Com.android.server.wm.WindowManagerService.setEventDispatching (windowmanagerservice.java:7628)
At com.android.server.am.ActivityManagerService.updateEventDispatchingLocked (activitymanagerservice.java:8083)
At Com.android.server.am.ActivityManagerService.wakingUp (activitymanagerservice.java:8077)
At Com.android.server.power.Notifier.sendWakeUpBroadcast (notifier.java:474)
At Com.android.server.power.Notifier.sendNextBroadcast (notifier.java:455)
At com.android.server.power.notifier.access$700 (notifier.java:62)
At Com.android.server.power.notifier$notifierhandler.handlemessage (notifier.java:600)
At Android.os.Handler.dispatchMessage (handler.java:107)
At Android.os.Looper.loop (looper.java:194)
At Com.android.server.ServerThread.run (systemserver.java:1328)

From the trace file, it is because the 24 thread of the TID waits for a lock that is held by the 12 thread of TID, and the thread of Tid 12 waits for a lock held by the thread of Tid 85, while the thread of Tid 85 waits for a lock held by a thread of TID 24, which causes the phenomenon of cyclic waiting. The statement for the corresponding trace file is as follows:

TID 24:-waiting to lock <0x41a874a0> (a Com.android.server.am.ActivityManagerService) held by Tid=12 (Android.serv Er. Serverthread)

TID:-Waiting to lock <0x41a7e2e8> (a Java.lang.Object) held by tid=85 (Binder_b)

TID 85:-waiting to lock <0x41a7e420> (a Com.android.server.power.powermanagerservice$displayblankerimpl) held by Tid=24 (Powermanagerservice)

Since it's a deadlock, look at all the threads that have those locks first.

First look at the top of the tid=24 thread, Activitymanagerservice's Broadcastintent function code is as follows:

Public final int broadcastintent (iapplicationthread caller,
Intent Intent, String resolvedtype, Iintentreceiver Resultto,
int ResultCode, String resultdata, Bundle map,
String Requiredpermission, Boolean serialized, Boolean sticky, int userId) {
Enforcenotisolatedcaller ("Broadcastintent");
Synchronized (this) {
Intent = verifybroadcastlocked (intent);

Final Processrecord Callerapp = getrecordforapplocked (caller);
Final int callingpid = Binder.getcallingpid ();
Final int callinguid = Binder.getcallinguid ();
Final Long Origid = Binder.clearcallingidentity ();
int res = broadcastintentlocked (Callerapp,
Callerapp! = null? CallerApp.info.packageName:null,
Intent, Resolvedtype, Resultto,
ResultCode, Resultdata, Map, requiredpermission, serialized, Sticky,
Callingpid, Callinguid, userId);
Binder.restorecallingidentity (Origid);
return res;
}

You can see that tid=24 needs to activitymanagerservice this lock. Looking at the top of the tid=12 thread, the Powermanagerservice isscreenoninternal function code is as follows:

Private Boolean isscreenoninternal () {
Synchronized (MLock) {
Return!msystemready
|| Mdisplaypowerrequest.screenstate! = Displaypowerrequest.screen_state_off;
}

}

You can see the Mlock this lock that needs powermanagerservice. Finally look at the tid=85 thread of the top of the stack, the same inside the Powermanagerservice, inner class Displayblankerimpl the ToString function:

Public String toString () {
Synchronized (this) {
Return "blanked=" + mblanked;
}
}

This is implemented within the inner class Displayblankerimpl, so you need to displayblankerimpl this lock.

The corresponding table is as follows:

Table one thread waits for lock condition

From table one, there is no deadlock, and it does not seem to be the case. Isn't it a deadlock? Started to be a little suspicious of themselves, for other reasons caused. Perhaps just look at the top of the call stack may not, the top of the stack can only see the locks required by each thread, can not just see what you want it! It is not good to ask blindly! That's not what people do! Take a look at the entire stack call flow and see if you have those locks.

Trace the stack of the tid=24 thread, holding the lock in the Unblankalldisplays function of the powermanagerservice inner class Displayblankerimpl:

public void Unblankalldisplays () {
Synchronized (this) {
Nativesetautosuspend (FALSE);
Nativesetinteractive (TRUE);
Mdisplaymanagerservice.unblankalldisplaysfrompowermanager ();
mblanked = false;
M:add for Tvout and HDMI
Mtvout.tvoutpowerenable (TRUE);
Mhdmi.hdmipowerenable (TRUE);
///@}
if (DEBUG) {
SLOG.D (Tag_p, "unblankalldisplays out ...");
}
if (mbootcompleted) {
Intent Intent = new Intent (action_lock_screen_show);
Mcontext.sendbroadcast (Intent);
}
}
}
The last code to send the broadcast is the one we added ourselves. Depending on the Unblankalldisplays function and the Broadcastintent function, you can see that the tid=24 thread now holds the Displayblankerimpl lock (unblankalldisplays), Wait for the Activitymanagerservice Lock (broadcastintent) to release.

Similarly, trace the stack of the tid=12 thread, holding the lock in the Activitymanagerservice wake_up function:

public void Wakingup () {
if (Checkcallingpermission (Android). Manifest.permission.DEVICE_POWER)
! = packagemanager.permission_granted) {
throw new SecurityException ("Requires permission"
+ Android. Manifest.permission.DEVICE_POWER);
}


Synchronized (this) {
SLOG.I (TAG, "Wakingup");
Mwenttosleep = false;
Updateeventdispatchinglocked ();
Comeoutofsleepifneededlocked ();
}
}

Depending on the Wakingup function and the isscreenoninternal function, you can see that the tid=12 thread holds the Activitymanagerservice lock (Wakingup), Wait for the Powermanagerservice.mlock lock (isscreenoninternal). To this, it seems to see hope, fog to push through, a little self-confidence is a deadlock caused, but can not be final conclusions.

Bang, which tracks the stack of tid=85 threads, has a lock-holding operation in the Powermanagerservice dump:

protected void Dump (FileDescriptor fd, PrintWriter pw, string[] args) {
....
Synchronized (MLock) {

...

}

Depending on the toString function and the dump function, you can see that the tid=85 thread now holds the Powermanagerservice.mlock lock (dump) and needs to be Displayblankerimpl (toString).

It seems that the answer has been revealed, if you have not seen (in fact, I did not see), a watch to see it!

Table two the situation of the lock of the line

Are you clear? What a clear cycle of waiting! Deadlock all die so perfect, or the chart effect is good, it seems sometimes on the paper painting or useful!

[Android Pro] analysis of deadlock ANR via Android trace file

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.