自 2025 年 3 月 27 日起,我们建议您使用 android-latest-release
而非 aosp-main
构建 AOSP 并为其做出贡献。如需了解详情,请参阅 AOSP 的变更。
使用 strace
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
通过 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
的 SELinux file_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
在完成上述更改之后,构建并刷写启动映像,设备会以宽容模式启动。
本页面上的内容和代码示例受内容许可部分所述许可的限制。Java 和 OpenJDK 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-03-26。
[null,null,["最后更新时间 (UTC):2025-03-26。"],[],[],null,["# Use strace\n\n[Strace](https://strace.io) enables you to see the system calls a\nprocess makes and what those system calls return.\n\nBuild strace\n------------\n\nTo build strace, run the following: \n\n```\nmmma -j6 external/strace\n```\n\nAttach to a running process\n---------------------------\n\nThe simplest and most common use case for strace is to attach it to a running\nprocess, which you can do with: \n\n```\nadb shell strace -f -p PID\n```\n\nThe `-f` flag tells strace to attach to all the threads in the\nprocess, plus any new threads spawned later.\n\nA typical process makes a lot of system calls, so you'll want to review the\n[strace man page](http://man7.org/linux/man-pages/man1/strace.1.html)\nto learn how to collect only data you're actually interested in.\n\nUse on an app\n-------------\n\nTo use strace on an app:\n\n1. 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: \n\n adb root\n adb shell setenforce 0\n adb shell stop\n adb shell start\n\n2. Set up a world-writable directory for strace logs, because strace will be running under the app's uid: \n\n adb shell mkdir -m 777 /data/local/tmp/strace\n\n3. Choose the process to trace and launch it: \n\n ```\n adb shell setprop wrap.com.android.calendar '\"logwrapper strace -f -o /data/local/tmp/strace/strace.com.android.calendar.txt\"'\n ```\n4. Launch the process normally.\n\nUse on the zygote\n-----------------\n\nTo use strace on the zygote, fix the relevant `init.rc` zygote\nline (requires `adb shell setenforce 0`): \n\n cd system/core/\n patch -p1 \u003c\u003cEOF\n --- a/rootdir/init.zygote32.rc\n +++ b/rootdir/init.zygote32.rc\n @@ -1,4 +1,4 @@\n -service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server\n +service zygote /system/bin/strace -o /data/local/tmp/zygote.strace /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server\n class main\n socket zygote stream 660 root system\n onrestart write /sys/android_power/request_state wake\n EOF\n\nGet strace logs during Android boot\n-----------------------------------\n\nTo get strace logs during Android boot, make the following changes:\n\n- Since the process name changes from `zygote` to `strace`, the given service may fail to start due to the missing SELinux `file_context` for `strace`. The solution is to add a new line for strace in `system/sepolicy/private/file_contexts` and copy the original file context over. Example: \n\n ```\n /dev/socket/zygote u:object_r:zygote_socket:s0\n + /system/bin/strace u:object_r:zygote_socket:s0\n ```\n- Add kernel or bootconfig parameter, then boot the device in SELinux permissive mode. You can do this by adding `androidboot.selinux=permissive`to `BOARD_KERNEL_CMDLINE`, or to `BOARD_BOOTCONFIG` in Android 12 with kernel version 5.10 or greater. (This variable becomes read-only in `build/core/Makefile` but is always available under `/device/*/BoardConfig`.) \n\n Example for the Pixel (sailfish) device in `/device/google/marlin/sailfish/BoardConfig.mk`: \n\n ```\n - BOARD_KERNEL_CMDLINE := .... androidboot.hardware=sailfish ...\n +BOARD_KERNEL_CMDLINE := .... androidboot.hardware=sailfish ... androidboot.selinux=permissive\n ```\n After making the change, build and flash the boot image and the device will boot in permissive mode."]]