如何获取 Binder 事务缓冲区的内容以进行故障排除

Posted

技术标签:

【中文标题】如何获取 Binder 事务缓冲区的内容以进行故障排除【英文标题】:How to get contents of Binder transaction buffer for troubleshooting 【发布时间】:2014-09-01 14:46:43 【问题描述】:

有没有办法通过编程或调试工具来了解 Binder 事务缓冲区中保存的当前事务?

有时,通常在运行数小时/数天后,我的应用程序崩溃并出现如下错误跟踪:

08-30 09:49:57.459  1879  1904 E JavaBinder: !!! FAILED BINDER TRANSACTION !!!
08-30 09:49:57.469  1879  1904 W BroadcastQueue: Exception when sending broadcast to ComponentInfocom.mycompany.myapp/com.mycompany.myapp.receiver.UpdateContentReceiver
08-30 09:49:57.469  1879  1904 W BroadcastQueue: android.os.TransactionTooLargeException
08-30 09:49:57.469  1879  1904 W BroadcastQueue:    at android.os.BinderProxy.transact(Native Method)
08-30 09:49:57.469  1879  1904 W BroadcastQueue:    at android.app.ApplicationThreadProxy.scheduleReceiver(ApplicationThreadNative.java:771)
08-30 09:49:57.469  1879  1904 W BroadcastQueue:    at com.android.server.am.BroadcastQueue.processCurBroadcastLocked(BroadcastQueue.java:231)
08-30 09:49:57.469  1879  1904 W BroadcastQueue:    at com.android.server.am.BroadcastQueue.processNextBroadcast(BroadcastQueue.java:778)
08-30 09:49:57.469  1879  1904 W BroadcastQueue:    at com.android.server.am.BroadcastQueue$1.handleMessage(BroadcastQueue.java:140)
08-30 09:49:57.469  1879  1904 W BroadcastQueue:    at android.os.Handler.dispatchMessage(Handler.java:99)
08-30 09:49:57.469  1879  1904 W BroadcastQueue:    at android.os.Looper.loop(Looper.java:137)
08-30 09:49:57.469  1879  1904 W BroadcastQueue:    at com.android.server.am.ActivityManagerService$AThread.run(ActivityManagerService.java:1487)

我尝试发送的广播没有额外内容,因此它的大小可以忽略不计。根据TransactionTooLargeException的文档:

Binder 事务缓冲区有一个有限的固定大小,目前为 1Mb,由进程正在进行的所有事务共享。因此,当有许多事务正在进行时,即使大多数单个事务的大小适中,也可能会引发此异常。

我的假设是缓冲区被其他东西(我的应用程序、我正在使用的库之一或系统)填满,当它快满时,它会抛出 TransactionTooLargeException。通过检查缓冲区的内容,我可以很容易地发现问题。

【问题讨论】:

【参考方案1】:

如http://www.slideshare.net/jserv/android-ipc-mechanism 的幻灯片 67 中所示,可以通过 debugfs 找到有关 Binder 事务缓冲区的详细信息。安装后

mount -t debugfs none /sys/kernel/debug

可以在/sys/kernel/debug/binder/ 中访问Binder 信息,在这里可以获得全局信息以及每个进程的信息。

【讨论】:

当问题发生时我无法访问设备时如何调试?我只有日志/dumpsys/dumpstate/dmesg/等。这是 debug-zip 的一部分,用于分析和修复问题。我遇到了和你一样的问题:没有额外内容的广播导致 TransactionTooLargeException

以上是关于如何获取 Binder 事务缓冲区的内容以进行故障排除的主要内容,如果未能解决你的问题,请参考以下文章

数据库三种故障及其恢复手段

如何理解 Android Binder 递归

Redis哨兵机制原理浅析

MSDTC故障排除

Android中的Binder事务失败[重复]

javabinder,失败的 BINDER 事务 - setImageViewBitmap(..) [重复]