jtrace - augmented, Linux/Android aware strace with plugin architecture

The jtrace tool is another one of my tools that started in order to address a shortcoming - in this case, the lack of strace(1) for ARM64. This was (somewhat) rectified with Google's finally providing one in their emulator image (which they finally produced as part of M), but the implementation is still buggy and falls short of the true power of system call tracing. So I decided to write my own. As in other cases, the tool evolved and actually became useful by its own right, so I'm releasing it. (I also feel bad about forgetting to give my Androidevotee followers a present like the one I gave the Applytes)

This tool is provided as one of the free downloads provided for the "Android Internals" book (http://NewAndroidBook.com/). You are welcome to use it even if you don't buy the book (though naturally you're even more welcome to buy the book :-). I used it extensively in my research, and provide plenty of use cases as experiments and examples in Volume II (especially for dealing with Binder).

The tool's latest version, as a tar file with binaries - presently ARM64 only, can always be obtained at this page right here. I'm working on making this work for ARM32, and more importantly x86, so it can be used for Linux, as well.

jtrace offers several significant advantages over strace(1):

For updates, you might want to check out the RSS feed, or follow my company's feed, @Technologeeks, which (aside from the occasional OS X/iOS related stuff) tweets about updates to this and other tools.


jtrace is designed to be as compatible with strace(1) as possible.

If you're not too familiar with strace(1), you ought to be - no native level developer, on any Linux or Android - can afford to remain unaware of this amazingly powerful piece of work. I myself owe a fair deal of my knowledge to countless hours spent using this tool to trace all sorts of binaries to figure out how things really work, without reading any source code (which often didn't exist openly).

As is usual, running it with no arguments will produce a usage message.

Usage: /data/local/tmp/jtrace64 [arguments]

STrace compatible options:
   -o _file_:  output to _file
   -f       :  follow forks
   -q: suppress output of syscalls with no installed handlers
   -p _pid_/name:   specify PID to trace. May also be a thread, or a process name
   -i:         print instruction pointer at time of syscall
   -t:         -t -- absolute timestamp, -tt -- with usecs
   -T:          print time spent in each syscall
   -y: print paths associated with file descriptor arguments
   -v: verbose mode

JTrace specific (that is, not found in strace)
   --color:    (because life is better with color!)
               Can also export/setenv JCOLOR=1 to make default
   --thread _name_: Attach to a process or thread with specific _name_
   --plugin:   Load a plugin (from $JTRACE_EXT_PATH). If not specified, all plugins load.


This is jtrace (64-bit) compiled on March  3 2016
Latest version always available for free at http://NewAndroidBook.com/tools/jtrace.html
Please visit http://NewAndroidBook.com/tools/counter?jtrace so I know you're using it :-)

Tracing property operations

All property set operations have to go through init - so to get those, just attach to it!

As you can see above, jtrace will show you the full operation involved - from getting the socket request, through checking SELinux, and the setting of the properties. But grep(1) is your friend if you just want to get the properties being set.

(you won't be able to trace property get operations - not due to a jtrace limitation, but because these are performed in-memory and do not involve syscalls)

Tracing input

Using --thread you can attach to system_server's InputReader thread (without needing to dig up its PID), and jtrace will be smart enough to figure when input events are involved, and decode them for you!

Tracing BINDER!

Binder, only the most critical and least comprehensible IPC/RPC mechanism in Android, is slowly yielding before jtrace! New version A) doesn't crash on it and B) already supports quite a few interfaces! You can isolate Binder messages by grep Method:

Note the use of -f to auto-attach to threads - since Binder spawns a thread pool (might crash in rare cases, I got that bug). I'm also working on deep message tracing (i.e. with arguments, like it does for servicemanager). If AIDL finally does cpp, this will make my life easier. Expect more soon.


Example Plugin Usage

JTrace now auto-loads plugins. Drop your plugin into the JTrace directory (specified by JTRACE_DIR JTRACE_EXT_PATH or in /data/local/tmp by default). With Android's ever-changing interfaces, this really makes sense. Take, for example, init's setprop feature. This has changed in Oreo to the setprop v2 format. Although jtrace innately supports v1, without a plugin v2 would look like this:

But with the plugin, it looks soooo much better:

Get the source of the sample plugin for init
Get the jtraceAPI.h (latest)


  • As is usual, jtrace shares no code with any other sources, open or closed, strace's, Android's, Google's or otherwise, save for a couple of BINDER ioctl(2) codes, and the Binder Data structures.
  • If you find this useful, pointing your browser to http://NewAndroidBook.com/tools/counter?jtrace - if I can ask you to cut/paste this (so bots don't auto-follow and I get a human count :-). would be appreciated.