Strace enables you to see the system calls a process makes and what those system calls return.
Build strace
To build strace, run the following:
mmma -j6 external/strace
Attach to a running process
The simplest and most common use case for strace is to attach it to a running process, which you can do with:
adb shell strace -f -p PID
The -f
flag tells strace to attach to all the threads in the
process, plus any new threads spawned later.
A typical process makes a lot of system calls, so you'll want to review the strace man page to learn how to collect only data you're actually interested in.
Use on an app
To use strace on an app:
- Set up the device so that you can run strace. You need to be root, disable SELinux, and restart
the runtime to remove the seccomp filter that will otherwise prevent strace from running:
adb root
adb shell setenforce 0
adb shell stop
adb shell start
- Set up a world-writable directory for strace logs, because strace will be running under the
app's uid:
adb shell mkdir -m 777 /data/local/tmp/strace
- Choose the process to trace and launch it:
adb shell setprop wrap.com.android.calendar '"logwrapper strace -f -o /data/local/tmp/strace/strace.com.android.calendar.txt"'
- Launch the process normally.
Use on the zygote
To use strace on the zygote, fix the relevant init.rc
zygote
line (requires adb shell setenforce 0
):
cd system/core/
patch -p1 <<EOF --- a/rootdir/init.zygote32.rc +++ b/rootdir/init.zygote32.rc @@ -1,4 +1,4 @@ -service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server +service zygote /system/bin/strace -o /data/local/tmp/zygote.strace /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server class main socket zygote stream 660 root system onrestart write /sys/android_power/request_state wake EOF
Get strace logs during Android boot
To get strace logs during Android boot, make the following changes:
- Since the process name changes from
zygote
tostrace
, the given service may fail to start due to the missing SELinuxfile_context
forstrace
. The solution is to add a new line for strace insystem/sepolicy/private/file_contexts
and copy the original file context over. Example:/dev/socket/zygote u:object_r:zygote_socket:s0 + /system/bin/strace u:object_r:zygote_socket:s0
- Add kernel or bootconfig parameter, then boot the device in SELinux permissive mode. You can
do this by adding
androidboot.selinux=permissive
toBOARD_KERNEL_CMDLINE
, or toBOARD_BOOTCONFIG
in Android 12 with kernel version 5.10 or greater. (This variable becomes read-only inbuild/core/Makefile
but is always available under/device/*/BoardConfig
.)
Example for the Pixel (sailfish) device in/device/google/marlin/sailfish/BoardConfig.mk
:- BOARD_KERNEL_CMDLINE := .... androidboot.hardware=sailfish ... +BOARD_KERNEL_CMDLINE := .... androidboot.hardware=sailfish ... androidboot.selinux=permissive
After making the change, build and flash the boot image and the device will boot in permissive mode.