Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android throw DeadObjectException with LOG: Transaction failed on small parcel; remote process probably died

07-22 04:38:07.933  1579  3338 E JavaBinder: !!! FAILED BINDER TRANSACTION !!!  (parcel size = 352)
07-22 04:38:07.933  1579  3338 W BroadcastQueue: Can't deliver broadcast to com.android.systemui (pid 2160). Crashing it.
07-22 04:38:07.934  1579  3338 W BroadcastQueue: Failure sending broadcast Intent { act=android.intent.action.TIME_TICK flg=0x50000014 (has extras) }
07-22 04:38:07.934  1579  3338 W BroadcastQueue: android.os.DeadObjectException: Transaction failed on small parcel; remote process probably died
07-22 04:38:07.934  1579  3338 W BroadcastQueue:    at android.os.BinderProxy.transactNative(Native Method)
07-22 04:38:07.934  1579  3338 W BroadcastQueue:    at android.os.BinderProxy.transact(Binder.java:618)
07-22 04:38:07.934  1579  3338 W BroadcastQueue:    at android.app.ApplicationThreadProxy.scheduleRegisteredReceiver(ApplicationThreadNative.java:1211)
07-22 04:38:07.934  1579  3338 W BroadcastQueue:    at com.android.server.am.BroadcastQueue.performReceiveLocked(BroadcastQueue.java:489)
07-22 04:38:07.934  1579  3338 W BroadcastQueue:    at com.android.server.am.BroadcastQueue.deliverToRegisteredReceiverLocked(BroadcastQueue.java:702)
07-22 04:38:07.934  1579  3338 W BroadcastQueue:    at com.android.server.am.BroadcastQueue.processNextBroadcast(BroadcastQueue.java:1002)
07-22 04:38:07.934  1579  3338 W BroadcastQueue:    at com.android.server.am.BroadcastQueue.processNextBroadcast(BroadcastQueue.java:799)
07-22 04:38:07.934  1579  3338 W BroadcastQueue:    at com.android.server.am.ActivityManagerService.finishReceiver(ActivityManagerService.java:19153)
07-22 04:38:07.934  1579  3338 W BroadcastQueue:    at android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:528)
07-22 04:38:07.934  1579  3338 W BroadcastQueue:    at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2909)
07-22 04:38:07.934  1579  3338 W BroadcastQueue:    at android.os.Binder.execTransact(Binder.java:565)
07-22 04:38:07.937  2160  2160 D AndroidRuntime: Shutting down VM
07-22 04:38:07.953  2160  2625 E JavaBinder: !!! FAILED BINDER TRANSACTION !!!  (parcel size = 136)
--------- beginning of crash
07-22 04:38:07.972  2160  2160 E AndroidRuntime: FATAL EXCEPTION: main
07-22 04:38:07.972  2160  2160 E AndroidRuntime: Process: com.android.systemui, PID: 2160
07-22 04:38:07.972  2160  2160 E AndroidRuntime: android.app.RemoteServiceException: can't deliver broadcast
07-22 04:38:07.972  2160  2160 E AndroidRuntime:    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1690)
07-22 04:38:07.972  2160  2160 E AndroidRuntime:    at android.os.Handler.dispatchMessage(Handler.java:102)
07-22 04:38:07.972  2160  2160 E AndroidRuntime:    at android.os.Looper.loop(Looper.java:160)
07-22 04:38:07.972  2160  2160 E AndroidRuntime:    at android.app.ActivityThread.main(ActivityThread.java:6252)
07-22 04:38:07.972  2160  2160 E AndroidRuntime:    at java.lang.reflect.Method.invoke(Native Method)
07-22 04:38:07.972  2160  2160 E AndroidRuntime:    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:898)
07-22 04:38:07.972  2160  2160 E AndroidRuntime:    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:788)

The error happened in the BroadcastQueue class, when it called scheduleRegisteredReceiver through Binder, the DeadObjectException throw. Like the LOG said: Transaction failed on small parcel; remote process probably died, but why RuntimeException throw in the com.android.systemui process if it already dead?

like image 723
Rick Ai Avatar asked Aug 01 '17 08:08

Rick Ai


1 Answers

Basically everything Rick Ai's answer to their own question is correct but here is a a real world example:

If your app creates and registers a whole bunch of BroadcastReceiver instances all listening to the same action--perhaps due to a leak or bug in your app--then the ActivityManagerService in the system process will invoke android.app.IApplicationThread method scheduleRegisteredReceiver for each registered instance. Notice that the binder transaction for this particular method is oneway. Since it is oneway each invocation will return immediately and the calls to the binder driver will occur very rapidly before each transaction is complete thus effectively running them all in parallel.

Lets say you have 100 receivers in your app and the broadcast being received contains 20 KiB of data. Now you've got 2 MiB trying to pass through the binder driver and it will fail due to the limit of 1 MiB.

In kernel logs you will see:

binder: 1282:1298 transaction failed 29201/-28, size 28052-8 line 3072

So beware leaking BroadcastReceiver and beware oneway binder transactions. Note that apparently the AIDL file may not declare a method oneway but it may end up that way if the AIDL compiler decides it is possible.

like image 118
satur9nine Avatar answered Sep 20 '22 06:09

satur9nine