3. strace 实战:追踪特定进程的系统调用、统计系统调用次数与耗时(-c)、过滤特定系统调用(-e)
strace 是 Linux 系统调用级性能分析的起点。它能够拦截并记录目标进程发起的每一次系统调用,包括调用名称、参数、返回值以及执行耗时。本章将围绕三个核心实战场景展开:追踪特定进程、统计系统调用次数与耗时、过滤特定系统调用。
实战前提:确保目标系统已安装 strace(通常位于
strace 包中)。若未安装,可使用 sudo apt install strace(Debian/Ubuntu)或 sudo yum install strace(RHEL/CentOS)快速安装。
3.1 追踪特定进程的系统调用
strace 支持两种方式追踪特定进程:附加到正在运行的进程(-p)和启动并追踪新进程(直接后跟命令)。
| 方式 | 命令示例 | 适用场景 |
|---|---|---|
| 附加到运行中进程 | strace -p <PID> |
追踪已启动的服务(如 nginx、mysqld) |
| 启动并追踪新进程 | strace <command> |
追踪一次性命令或脚本 |
| 追踪多线程进程 | strace -f -p <PID> |
追踪所有子线程和子进程 |
关键参数:
-f 跟踪由 fork/vfork/clone 创建的子进程;-ff 将每个进程的输出分离到独立文件(需配合 -o 指定输出前缀)。
以下 SVG 展示了 strace 附加到运行中进程的数据流:
3.1.1 实战:追踪 nginx worker 进程
# 查找 nginx worker 进程 PID
$ ps aux | grep 'nginx: worker'
www-data 12345 0.0 0.1 ... nginx: worker process
# 附加追踪,输出到文件
$ sudo strace -p 12345 -o /tmp/nginx_strace.log
# 若 nginx 使用多进程,追踪所有 worker
$ sudo strace -f -p $(pgrep -d',' -f 'nginx: worker') -o /tmp/nginx_all_workers.log
注意:使用
-p 附加到运行中进程需要 root 权限或与目标进程相同的用户权限。追踪生产环境服务时,建议先使用 -c 统计模式评估开销,再决定是否开启详细追踪。
3.2 统计系统调用次数与耗时(-c)
-c 参数是 strace 性能分析的核心开关。它不会逐行打印每次系统调用,而是在程序退出或用户中断时,汇总输出一份统计报告,包含每个系统调用的次数、总耗时、平均耗时、错误次数等信息。
| 统计列 | 含义 | 性能分析价值 |
|---|---|---|
% time |
该系统调用耗时占总耗时的百分比 | 快速定位最耗时的系统调用 |
seconds |
该系统调用累计耗时(秒) | 量化性能瓶颈的绝对时间 |
usecs/call |
每次调用的平均耗时(微秒) | 判断单次调用是否异常 |
calls |
调用次数 | 识别高频调用路径 |
errors |
返回错误的次数 | 发现异常或资源耗尽问题 |
3.2.1 实战:统计 ls 命令的系统调用
$ strace -c ls /tmp
... (ls 正常输出) ...
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
35.21 0.000412 68 6 getdents64
22.65 0.000265 44 6 newfstatat
18.80 0.000220 36 6 write
8.55 0.000100 50 2 openat
5.98 0.000070 35 2 close
4.27 0.000050 25 2 mmap
2.56 0.000030 15 2 munmap
1.71 0.000020 20 1 brk
0.27 0.000003 3 1 read
------ ----------- ----------- --------- --------- ----------------
100.00 0.001170 28 total
从统计结果可以清晰看到:getdents64(读取目录项)耗时占比最高(35.21%),newfstatat(获取文件状态)紧随其后。对于 ls 这种目录遍历命令,这两个系统调用是核心瓶颈。
性能分析技巧:当
usecs/call 值异常偏高时(例如 read 平均耗时超过 1000 微秒),通常意味着磁盘 I/O 延迟或锁竞争。此时应结合 perf 进一步采样内核事件。
以下 SVG 展示了 -c 统计模式的数据处理流程:
3.3 过滤特定系统调用(-e)
当系统调用数量庞大时(例如数据库服务每秒数万次调用),全量追踪会产生海量数据,干扰分析。strace 的 -e 参数允许按系统调用名称、系统调用类别或文件描述符进行过滤。
| 过滤方式 | 语法 | 示例 |
|---|---|---|
| 按名称包含 | -e trace=<syscall> |
-e trace=read,write |
| 按名称排除 | -e trace=!<syscall> |
-e trace=!futex |
| 按类别过滤 | -e trace=<category> |
-e trace=file(文件相关) |
| 按文件描述符 | -e read=<fd> |
-e read=3(仅追踪 fd=3 的读取) |
3.4.1 常用系统调用类别
| 类别名 | 包含的系统调用 | 分析场景 |
|---|---|---|
file |
open, close, read, write, stat, unlink 等 |
文件 I/O 性能分析 |
process |
fork, execve, wait, exit 等 |
进程创建与销毁分析 |
network |
socket, connect, send, recv, accept 等 |
网络 I/O 性能分析 |
ipc |
shmget, semop, msgrcv 等 |
进程间通信分析 |
desc |
所有与文件描述符相关的系统调用 | 文件描述符泄漏排查 |
3.4.2 实战:过滤 MySQL 的磁盘 I/O 系统调用
# 仅追踪 MySQL 的 read/write/pwrite/pread 系统调用
$ sudo strace -p $(pidof mysqld) -e trace=read,write,pwrite64,pread64 -o /tmp/mysql_io.log
# 排除 futex(锁相关),减少噪声
$ sudo strace -p $(pidof mysqld) -e trace=!futex -o /tmp/mysql_no_futex.log
# 按类别过滤:仅追踪网络相关系统调用
$ sudo strace -p $(pidof mysqld) -e trace=network -o /tmp/mysql_network.log
组合使用:
-e 可以与 -c 联合使用,实现“只统计特定系统调用的性能数据”。例如:strace -c -e trace=read,write -p <PID> 将只统计 read 和 write 的调用次数与耗时。
以下 SVG 展示了 -e 过滤机制在 strace 内部的处理逻辑:
3.4 实战组合:过滤 + 统计 + 输出到文件
将 -e、-c 和 -o 组合使用,可以实现低开销、高精度的系统调用级性能分析:
# 组合示例:仅统计文件 I/O 系统调用,输出到文件
$ sudo strace -c -e trace=file -p $(pidof mysqld) -o /tmp/mysql_file_stat.log
# 组合示例:排除 futex,统计所有其他系统调用
$ sudo strace -c -e trace=!futex -p $(pidof mysqld) -o /tmp/mysql_no_futex_stat.log
# 组合示例:仅追踪 read/write,并输出详细日志
$ sudo strace -e trace=read,write -p $(pidof mysqld) -o /tmp/mysql_rw_detail.log
性能分析工作流建议:
- 先使用
-c -e trace=!futex快速获取全局统计,识别热点系统调用。 - 针对热点系统调用(如
read、write、poll),使用-e trace=<hot_syscall>输出详细日志。 - 结合
perf对热点系统调用的内核路径进行采样,定位具体瓶颈函数。
3.5 常见问题与避坑
| 问题 | 原因 | 解决方案 |
|---|---|---|
| strace 输出为空 | 目标进程已退出或权限不足 | 使用 sudo;确认 PID 存在 |
| strace 导致目标进程变慢 | ptrace 拦截引入巨大开销 | 使用 -c 统计模式;使用 -e 过滤;减少追踪时间 |
| 输出文件过大 | 未使用过滤,全量追踪 | 使用 -e 限制范围;使用 -c 替代详细输出 |
| 多线程进程追踪混乱 | 未使用 -f 参数 |
添加 -f 追踪所有线程;使用 -ff 分离输出 |
生产环境警告:strace 的 ptrace 机制会大幅降低目标进程性能(通常 10x~100x 减速)。在生产服务器上,建议仅在低峰期使用
-c 统计模式,且追踪时间不超过 30 秒。如需长时间追踪,优先考虑 perf trace 或 eBPF 方案。
通过本章实战,你已经掌握了 strace 的三个核心能力:追踪特定进程、统计系统调用次数与耗时、过滤特定系统调用。这些技能是后续与 perf 联用进行深度性能分析的基础。