Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get contents of Binder transaction buffer for troubleshooting

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.

like image 873
ris8_allo_zen0 Avatar asked Jan 10 '23 22:01

ris8_allo_zen0


1 Answers

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.

like image 135
ris8_allo_zen0 Avatar answered Mar 11 '23 22:03

ris8_allo_zen0