The bindump utility is a little tool I've put together for my book, after realizing that there's no tool I know of, AOSP or other, which can map out which PIDs communicate over Binder with which. I needed this type of mapping for the chapter dealing with the Framework Services, as well as the long discussion on Binder Internals. The book is still not done (but, honestly, this year!), yet this tool is usable on its own. And is super simple, yes, though darn useful.

You can get the tool right here, as a tar with ARMv7 and ARMv8 (ARM64) binaries. The binaries should work on any Android 9 or higher. I've even worked around for Samsung oddities, and for Android 11 preview. As usual, you might want to check out the RSS feed, or follow my company's Twitter for more updates.

Why should I care?

If you've called Context.getSystemService(..), you've been using Binder (through proxy objects). The owning PID of most of these services is system_server, but not always - notable exceptions being the phone and batterypropregistrar. Vendor installed services sometimes also run in their own processes.

If you want to get a better idea of who's talking to whom in your device - this is a pretty good tool for that. From the /proc filesystem perspective, all you'll see is a file descriptor to /dev/binder - but this tool goes a step further to show you the actual Binder sessions. At this point, only for published services. I'll work on updating that by the time the book is out.

So how do I use it?

Glad you asked. Usage couldn't be simpler. Unlike the original version of this tool, this now requires root privileges for the full power:

flame:/ $ /data/local/tmp/bindump                                                                                                   
Usage: bindump [-h|-?]
       bindump [ns] list
       bindump [ns] check SERVICE
       bindump [ns] users SERVICE  # As per my 'bindump' tool
Where: [ns] is optionally 'binder' (default), 'hwbinder' or 'vndbinder'

This tool is part of the resources for 'Android Internals', Volume II
Free for non-commercial use at
For commercial use (and pure C binder library) mail://
flame:/ $ /data/local/tmp/bindump check power
Service power: found
flame:/ $ /data/local/tmp/bindump check powerf                                                                                       
Service powerf: not found
1|flame:/ $ /data/local/tmp/bindump list                                               
0: gsiservice
1: sip

It gets better when you have root. for example, you can now inspect the vndbinder namespace:

flame:/ # /data/local/tmp/bindump vndbinder list
0: media.ecoservice
1: airbrush_tpu
2: airbrush_faceauth
3: vendor.qcom.PeripheralManager
4: rlsservice
5: power.stats-vendor
6: display.qservice

With the real kicker being "users" -

flame:/ # /data/local/tmp/bindump vndbinder users airbrush_tpu                                                                        Service 'airbrush_tpu' is node 1014
	User:     859 (/vendor/bin/hw/android.hardware.neuralnetworks@1.2-service-noronha)
	Owner:    875 (/vendor/bin/hw/
	User:     612 (/vendor/bin/vndservicemanager)

# Can also do 'all' for SERVICE name:
flame:/ $ /data/local/tmp/bindump vndbinder users all
Service 'media.ecoservice' is node 1346
	Owner:    881 (media.hwcodec)
	User:     849 (/vendor/bin/hw/
	User:     612 (/vendor/bin/vndservicemanager)
Service 'airbrush_tpu' is node 1014
	User:     859 (/vendor/bin/hw/android.hardware.neuralnetworks@1.2-service-noronha)
	Owner:    875 (/vendor/bin/hw/
	User:     612 (/vendor/bin/vndservicemanager)
Service 'airbrush_faceauth' is node 1010
	Owner:    875 (/vendor/bin/hw/
	User:     612 (/vendor/bin/vndservicemanager)
Service 'vendor.qcom.PeripheralManager' is node 951
	User:     978 (/vendor/bin/hw/qcrildmp)
	User:     994 (/vendor/bin/cnss-daemon)
	Owner:    921 (/vendor/bin/pm-servicen)
	User:    1010 (/vendor/bin/pm-proxycen)
	User:     856 (/vendor/bin/hw/android.hardware.gnss@2.0-service-qtid_untrusted_context=u:r:blkid_untrusted:s0)
	User:     612 (/vendor/bin/vndservicemanager)
Service 'rlsservice' is node 771
	User:     867 (/vendor/bin/hw/android.hardware.sensors@2.0-serviceid_untrusted_context=u:r:blkid_untrusted:s0)
	Owner:    874 (/vendor/bin/rlsservice.hardware.sensors@2.0-serviceid_untrusted_context=u:r:blkid_untrusted:s0)
	User:     612 (/vendor/bin/vndservicemanager)
Service 'power.stats-vendor' is node 639
	Owner:    863 (/vendor/bin/hw/android.hardware.power.stats@1.0-service.pixeled_context=u:r:blkid_untrusted:s0)
	User:     620 (/vendor/bin/hw/citadeldhardware.power.stats@1.0-service.pixeled_context=u:r:blkid_untrusted:s0)
	User:     612 (/vendor/bin/vndservicemanager)
Service 'display.qservice' is node 225
	Owner:    655 (/vendor/bin/hw/
	User:     612 (/vendor/bin/vndservicemanager)
Service '' is node 8
	User:     872 (/vendor/bin/hw/android.hardware.weaver@1.0-service.citadell)
	User:     847 (/vendor/bin/hw/
	User:     621 (/vendor/bin/hw/
	Owner:    620 (/vendor/bin/hw/
	User:     612 (/vendor/bin/vndservicemanager)

'users' tells you which processes have handles to the service (real-time of course), AND who owns the node! This is REALLY useful. For example, try users power to see who holds wakelocks, or users SurfaceFlinger for whoever has views:

flame:/ # /data/local/tmp/bindump users SurfaceFlinger                                                                               
Service 'SurfaceFlinger' is node 445
	User:    4052 (com.topjohnwu.magisk)
	User:    3034 (
	User:    2223 (
	User:    1956 (com.breel.wallpapers19)
	User:    1881 (
	Owner:    653 (/system/bin/surfaceflinger)
	User:     610 (/system/bin/servicemanager)

Note servicemanager (or [vnd/hw]servicemanager) are always users - that's because they need to give out the handle on lookup

How does it work?

Ah. An even better question. While a discussion of Binder is outside the scope of this little write-up (and, hey, it's in the book!), this tool's functionality is simple enough to explain in a few lines:

Example: healthd (owner of batterypropreg):

shell@htc_m8wl:/ $ cat /sys/kernel/debug/binder/proc/364                       
binder proc state:
proc 364
  thread 364: l 02
  node 17: u018317a0 c01830704 hs 1 hw 1 ls 0 lw 0 is 2 iw 2 proc 25871 366
  ref 15: desc 0 node 1 s 1 w 1 d   (null)          # Ref to ServiceManager
  ref 777219: desc 1 node 777218 s 1 w 1 d ed9b5600 # Owner of batterypropreg

And that's that.

I'm working on improvements to adapt this to non published services (i.e. any binder nodes), as well as produce SVG output. And I'm always looking for suggestions. So stay tuned.

When will it not work?

License notes, etc

Free for non commercial use. Not open source, due to blatant ripoff of its previous version (which is, btw, why it now requires root - Google didn't like it either...). The original source of the previous version is here. The source is nothing fancy - it takes that of service.cpp as a point of departure, but then embarks on its own journey. The updated source is a full re-write, using a Binder pure C interface I (painstakingly) wrote from scratch.

Shameless plug for the book, and RFC

The forever-delayed Volume II has a TON of detail about the framework services, and volume II covers the nooks and crannies of Binder in places where I betcha Dianne Hackborn herself (Love your work!) might feel uncomfortable ;-). The book is not out yet, but with MOXiI out of the way, and nothing to do locked down at home, it's finally progressing! In the interim, I encourage you to try out the tool (as well as the even more powerful JTrace) and shoot me an email (to j@) if you've any questions. Or comments. Or in general. All are welcome.

Also - Technologeeks' training on Android Internals is still set for early June, barring COVID-19 delays.. I discuss all the nooks and crannies of Binder, and more.