strace安卓linux系统调用跟踪神器相关实战案例
-
一、什么是strace? -
二、strace的工作原理 -
三、strace的核心作用 -
四、常用参数与用法 -
五、典型使用场景与案例 -
场景一:程序启动失败,排查缺少文件或配置 -
场景二:定位“Permission denied”的具体原因 -
场景三:诊断进程卡死(hang)或无响应 -
场景四:分析程序启动慢的原因 -
场景五:跟踪多进程/多线程程序 -
六、进阶技巧 -
1. 过滤输出 -
2. 显示系统调用的耗时 -
3. 输出更完整的字符串 -
4. 将strace作为调试器使用 -
七、安卓中strace一些实战案例技巧 -
八、注意事项
本文将全面介绍 strace 命令的作用、工作原理、常见使用场景以及实战案例,帮助你掌握这一强大的调试工具。
一、什么是strace?
strace 是一个集诊断、调试、分析于一体的Linux系统工具,它可以拦截并记录进程发起的所有系统调用(system call)以及接收到的信号。简单来说,它能让你“看见”一个程序在运行时,向内核发出了什么请求,内核又是如何响应的。
系统调用是用户态程序与内核交互的唯一入口,比如读写文件(open, read, write)、创建进程(fork, clone)、网络通信(socket, connect, send)等。通过观察这些调用,我们可以精准地定位程序在哪个环节出现了问题。

二、strace的工作原理
strace 的背后依赖于Linux内核提供的 ptrace 系统调用。ptrace 允许一个进程(trace)监视和控制另一个进程(tracee)的执行,并可以读取和修改其内存和寄存器。
当一个进程被 strace 附加后,每次该进程执行系统调用时,内核都会暂停该进程,并将控制权转交给 strace 进程。strace 会解析系统调用的编号、参数、返回值,并将其以人类可读的格式输出,然后恢复原进程的执行。这个过程中,原进程的性能会有所下降,但对于诊断问题来说,这种开销通常是可接受的。
三、strace的核心作用
-
故障排查:当程序崩溃、无响应、权限错误或找不到文件时, strace可以快速定位失败的系统调用及其错误码。 -
性能分析:通过统计系统调用的耗时和频次,可以找出程序性能瓶颈。例如,过多的 open或stat调用可能意味着频繁的文件访问,导致I/O等待。 -
理解程序行为:对于没有源代码或文档的程序, strace可以揭示其工作流程:读取了哪些配置文件、打开了哪些动态库、监听了哪些端口等。
四、常用参数与用法
|
|
|
|---|---|
-p PID |
|
-o file |
|
-e trace=set |
-e trace=file 只跟踪文件操作 |
-t
-tt / -ttt |
|
-T |
|
-f |
|
-c |
|
-s size |
|
五、典型使用场景与案例
Android与Linux跟踪方式的区别 必须获取root权限。因为strace需要访问内核空间的信息,未root设备不允许此操作。
场景一:程序启动失败,排查缺少文件或配置
假设我们运行一个名为 myapp 的程序,但它启动后立即退出,没有输出任何错误信息。
strace -o strace.log ./myapp
查看 strace.log 文件,通常会看到类似这样的内容:
openat(AT_FDCWD, "/etc/myapp/config.conf", O_RDONLY) = -1 ENOENT (No such file or directory)
这就明确指出了程序因为找不到 /etc/myapp/config.conf 而退出,问题一目了然。
场景二:定位“Permission denied”的具体原因
有时程序报告权限错误,但不知道是哪个文件或目录的权限有问题。
strace -e trace=open,openat -o strace.log ./myapp
通过过滤只跟踪文件打开操作,可以快速找到第一个返回 EACCES 的调用。
场景三:诊断进程卡死(hang)或无响应
当发现一个服务进程没有响应,但进程还在,可能是死锁、等待资源或陷入某个系统调用。可以用 strace 附加到进程看看它在做什么:
strace -p 12345
如果输出反复出现:
futex(0x7f1234567890, FUTEX_WAIT_PRIVATE, 2, NULL) = ?
说明进程正在等待一个互斥锁,可能发生了死锁。如果输出是:
read(3,
并一直停在那里,说明进程在等待从文件描述符3读取数据,可能是网络或管道输入卡住了。
场景四:分析程序启动慢的原因
一个应用启动时间过长,可以使用 strace 跟踪启动过程,并统计耗时:
strace -c -f ./slow_app
命令执行后,strace 会输出一张汇总表:
% time seconds usecs/call calls errors syscall------ ----------- ----------- --------- --------- ---------------- 72.34 2.345678 23456 100 read 15.12 0.490000 4900 100 open 8.21 0.266000 266 1000 stat 4.33 0.140000 140 1000 mmap
从表中可以看出,read 调用占据了大部分时间,且平均耗时很高,这提示我们程序可能在大量读取数据,或者读取操作本身存在性能问题。
场景五:跟踪多进程/多线程程序
对于会创建子进程的程序(如web服务器),需要使用 -f 参数来跟踪所有子进程:
strace -f -o strace.log ./nginx
对于多线程程序,使用 -f 同样可以跟踪所有线程的系统调用,因为Linux内核中线程是通过轻量级进程实现的。
六、进阶技巧
1. 过滤输出
当输出信息过多时,可以使用 -e 过滤:
-
-e trace=file:仅跟踪文件操作 -
-e trace=process:仅跟踪进程管理(fork, exec等) -
-e trace=network:仅跟踪网络操作 -
-e trace=signal:仅跟踪信号处理
也可以使用 -e trace=!xxx 来排除某些调用,如 -e trace=!futex 排除干扰较多的锁操作。
2. 显示系统调用的耗时
使用 -T 参数,每个系统调用后会显示耗时(括号内的数字):
open("/etc/passwd", O_RDONLY) = 3 <0.000015>
3. 输出更完整的字符串
默认情况下,字符串参数只显示前32个字符。使用 -s 1024 可以显示更长的内容,对查看完整的路径名或数据包内容很有帮助。
4. 将strace作为调试器使用
结合 -i 参数,可以显示系统调用发生的指令指针地址,配合 objdump 或 gdb 可以进一步定位到源代码行。
七、安卓中strace一些实战案例技巧
一般debug版本会自带strace,没有的话大家可以自己编译make strace后进行push
追踪apk启动过程
上面介绍是linux和android都通用的命令strace命令,一般都是针对具体的native的bin文件启动,但是在android上面,如果要监测某个apk启动时候会触发哪些系统调用呢?
步骤1:获取zygote进程PID
emulator_car64_x86_64:/ # ps -A | grep zygoteroot 523 1 17187420 174404 do_sys_poll 0 S zygote64webview_zygote 1174 523 33899408 115312 do_sys_poll 0 S webview_zygote
记录zygote的PID为523.
步骤2:启动strace跟踪zygote
# 跟踪zygote及其所有子进程,输出到文件strace -f -tt -T -s 500 -p 523 -o /sdcard/strace_output.txt
参数说明:
-f:跟踪所有子进程(必须!)
-tt:显示微秒级时间戳
-T:显示每个系统调用的耗时
-s 500:显示更多字符串内容(默认32字节)
-p 523:附加到zygote进程
-o:输出到文件
步骤3:启动目标APK 保持terminal中的strace运行抓取中,然后在桌面点击app打开既可以。 步骤4:停止跟踪 应用启动完成后,在strace终端按 Ctrl+C 停止跟踪,然后拉取日志:
adb pull /sdcard/strace_output.txt .
追踪app进程被卡住案例
假设代码中故意加入一个卡顿10s的sleep,看看是否使用strace可以定位出来:
查看audiotrackdemo的pid号:
ps -A|grep track u10_a211 4563 523 16282832 168612 do_epoll_wait 0 S com.example.audiotrackdemo
使用strace追踪上面的pid对应进程:
strace -tt -T -p 4563 -o /sdcard/strace.txt
点击app按钮触发sleep 10s行为,然后等待10s以后中断strace抓取行为,pull出对应文件:
adb pull /sdcard/strace.txt/sdcard/strace.txt: 1 file pulled, 0 skipped. 62.9 MB/s (1025485 bytes in 0.016s)
查看strace.txt文件定位: 确实看到有10s的系统调用
11:19:12.988345 futex(0x7c33ed933b90, FUTEX_WAIT_PRIVATE, 352, {tv_sec=10, tv_nsec=0}) = -1 ETIMEDOUT (Connection timed out) <10.000084>
八、注意事项
-
权限:普通用户只能 strace自己启动的进程,跟踪其他用户的进程需要root权限。 -
性能开销: strace会显著降低目标进程的执行速度,尤其是在大量系统调用的场景下。生产环境使用时需谨慎,或仅在短期诊断时使用。 -
安全风险: strace可以读取进程的内存数据,可能泄露敏感信息(如密码、密钥)。在跟踪涉及敏感数据的进程时,应妥善处理输出文件。更多vip免费系统开发经典大厂面试题库获取,课程优惠购买成为vip学员进入vip群,积极讨论各种行业难点痛点疑难问题,答疑服务等。
请联系马哥:
目前所有专题课程如下: 1、经典fw的入门到精通实战八件套专题 
详细课表: Android Framework开发rom实战合集课表/车载车机手机高级系统开发工程必会技能
夜雨聆风