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.ActivityManager Service.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.PowerManagerSer Vice$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.PowerManag Erservice.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 r Esultdata, Bundle map, String requiredpermission, Boolean serialized, Boolean St Icky, int userId) { Enforcenotisolatedcaller ("broadcastintent"); s Ynchronized (this) { Intent = verifybroadcastlocked (intent); final Processrecord Callerapp = Getrecordforapplocke D (caller); final int callingpid = Binder.getcallingpid (); final int callinguid = Binder.getcallinguid (); final long origid = Binder.clearcalliNgidentity (); int res = broadcastintentlocked (Callerapp, &N Bsp Callerapp! = null? CallerApp.info.packageName:null, Intent, Resolvedt Ype, Resultto, ResultCode, resultdata, map, required Permission, serialized, Sticky, Callingpid, Callingu ID, 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 (thi s) { Nativesetautosuspend (false), &NBS P nativesetinteractive (true); Mdisplaymanagerservice.unblankalldisplaysfrompowermanager (); mblanked = false; ///m:add for tvout and HDMI &N Bsp Mtvout.tvoutpowerenable (true); Mhdmi.hdmipowe Renable (True); ///@} &NBS P if (DEBUG) { SLOG.D (tag_p, "Unblankall Displays out ... "); if (mbootcompleted) { & nbsp intent Intent = new Intent (action_lock_screen_show); mcontext.sendbroadcast (intent); } } } last send broadcast generation Code, which 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 Securityex Ception ("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