Android抛出带有LOG的DeadObjectException:小宗交易失败;远程进程可能死了 [英] Android throw DeadObjectException with LOG: Transaction failed on small parcel; remote process probably died

查看:571
本文介绍了Android抛出带有LOG的DeadObjectException:小宗交易失败;远程进程可能死了的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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)

该错误发生在BroadcastQueue类中,当它通过Binder调用scheduleRegisteredReceiver时,抛出DeadObjectException异常。就像LOG所说:小包裹交易失败;远程进程可能死了,但是如果RuntimeException已经死了,为什么还要在com.android.systemui进程中抛出RuntimeException?

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?

推荐答案

我终于找到了根本原因,它发生在绑定程序内核中。

I finally found the root cause, it happened in the binder kernel.

现在,我发现了导致DeadObjectException抛出广播广播队列和随后的原因的两个原因应用程序中ActivityThread中的RemoteServiceException:

For now, I discovered two reasons for what can cause a DeadObjectException to be thrown in BroadcastQueue and therafter a RemoteServiceException in ActivityThread in the app:


  1. 当AMS发送单向联编程序调用时,不再有异步空间来执行联编程序事务到ActivityThread以触发BroadcastReceiver.onReceive。

相关代码如下所示:

kernel/msm-4.4/drivers/android/binder_alloc.c
290     if (is_async &&
291            alloc->free_async_space < size + sizeof(struct binder_buffer)) {
292           binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC,
293                         "%d: binder_alloc_buf size %zd failed, no async space left\n",
294                           alloc->pid, size);
295            eret = ERR_PTR(-ENOSPC);
296              goto error_unlock;
297    }

因此,这不会破坏系统的稳定性。只会影响应用程序本身。

Therefore, this will not "end up destabilizing the system". It will only influences the application itself.


  1. 由于广播队列将scheduleCrash绑定程序调用发送给ActivityThread,因此用户应用程序已被强制关闭。 。造成此问题的根本原因是,在应用程序端没有绑定程序缓冲区,因为某些绑定程序线程占据了其中的大部分。

可以通过以下步骤触发错误:

The bug can be triggered with the following steps:


  1. Process1向Process2发送大数据(例如980kB),Process2需要休眠30秒,

  2. Process1将广播发送到Process2,例如, 50kB数据。这将超出使缓冲区容量为1016kB的范围,因为980kB + 50kB大于缓冲区容量。

  3. BroadcastQueue将抛出DeadObjectException,然后将scheduleCrash传递给应用程序端的ActivityThread。

这是代码:

kernel/msm-4.4/drivers/android/binder_alloc.c
 315     if (best_fit == NULL) {
...
341         pr_err("%d: binder_alloc_buf size %zd failed, no address space\n",
342                   alloc->pid, size);
343         pr_err("allocated: %zd (num: %zd largest: %zd), free: %zd (num: %zd largest: %zd)\n",
344                       total_alloc_size, allocated_buffers, largest_alloc_size,
345                  total_free_size, free_buffers, largest_free_size);
346            eret = ERR_PTR(-ENOSPC);
347              goto error_unlock;
348    }

总而言之,即使应用程序进程尚未完成,也可能引发DeadObjectException死了

In conclusion, DeadObjectException can be thrown even if the application process haven't died.

最根本的原因很可能是因为应用程序具有完整的活页夹缓冲区,并且不影响系统。

The root cause is most likely because of full binder buffer for the application and does not influence the system.

所以我认为在广播队列中捕获DeadObjectException之后,不必使应用程序崩溃。

So I think it is not necessary to make the application crash after catching a DeadObjectException in BroadcastQueue.

这篇关于Android抛出带有LOG的DeadObjectException:小宗交易失败;远程进程可能死了的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆