Is there a way, either programmatically or through a debugging tool, to know the current transactions held in the Binder transaction buffer?
Sometimes, usually after hours/days of run, my app crashes with an error trace like this:
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 ComponentInfo{com.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)
The broadcast I was trying to send has no extras, so it has negligible size. As per documentation of TransactionTooLargeException:
The Binder transaction buffer has a limited fixed size, currently 1Mb, which is shared by all transactions in progress for the process. Consequently this exception can be thrown when there are many transactions in progress even when most of the individual transactions are of moderate size.
My hypotesis is that the buffer is filled up by something else (my app, one of the libraries I'm using or the system) and when it's almost full, it throws TransactionTooLargeException
. By inspecting the contents of the buffer, I could easily spot the problem.
As found in slide 67 of http://www.slideshare.net/jserv/android-ipc-mechanism, detailed information about the Binder transaction buffer can be found through debugfs. After mounting it with
mount -t debugfs none /sys/kernel/debug
the Binder info can be reached in /sys/kernel/debug/binder/
, where one can get global as well as per-process information.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With