通过 Strace,您可以看到进程发出的系统调用,以及这些系统调用返回的内容。
构建 strace
要构建 strace,请运行以下命令:
mmma -j6 external/strace
附加到正在运行的进程
对于 strace,最简单和最常见的用例即是附加到正在运行的进程,方法是使用下面这行命令:
adb shell strace -f -p PID
-f
标志告诉 strace 应附加到相应进程中的所有现有线程,以及之后会产生的所有新线程。
一个典型进程会发出大量系统调用,因此您需要查看 strace 手册页面,了解如何只收集您真正感兴趣的数据。
在应用中使用
如需对应用使用 strace,请执行以下操作:
- 设置设备,以便您可以运行 strace。您必须启用 root 权限、停用 SELinux,然后重新启动运行时以移除 seccomp 过滤器,否则此过滤器会阻止 strace 运行:
adb root
adb shell setenforce 0
adb shell stop
adb shell start
- 为 strace 日志设置一个全局可写目录,因为 strace 将在应用的 uid 下运行:
adb shell mkdir -m 777 /data/local/tmp/strace
- 选择要跟踪的进程并启动该进程:
adb shell setprop wrap.com.android.calendar '"logwrapper strace -f -o /data/local/tmp/strace/strace.com.android.calendar.txt"'
- 正常启动该进程。
在 zygote 上使用
如需在 zygote 上使用 strace,请修复相关的 init.rc
zygote 行(需要使用 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
获取 Android 启动期间的 strace 日志
如需获取 Android 启动期间的 strace 日志,请执行以下更改:
- 由于进程名称已从
zygote
改为strace
,给定服务可能会因缺少用于strace
的 SELinuxfile_context
而无法启动。解决方法:在system/sepolicy/private/file_contexts
中为 strace 添加一个新行,并将原始文件上下文复制过来。示例:/dev/socket/zygote u:object_r:zygote_socket:s0 + /system/bin/strace u:object_r:zygote_socket:s0
- 添加内核参数或 bootconfig 参数,然后在 SELinux 宽容模式下启动相应设备。为此,您可以将
androidboot.selinux=permissive
添加到BOARD_KERNEL_CMDLINE
,也可以添加到BOARD_BOOTCONFIG
(在内核版本为 5.10 或更高版本的 Android 12 中)。(此变量在build/core/Makefile
中会变为只读,但在/device/*/BoardConfig
下则始终可用。)
/device/google/marlin/sailfish/BoardConfig.mk
中 Pixel (sailfish) 设备的示例: 在完成上述更改之后,构建并刷写启动映像,设备会以宽容模式启动。- BOARD_KERNEL_CMDLINE := .... androidboot.hardware=sailfish ... +BOARD_KERNEL_CMDLINE := .... androidboot.hardware=sailfish ... androidboot.selinux=permissive