2. strace 基础选项:-c 统计、-e 过滤、-o 输出文件、-p 附加进程
strace 是 Linux 系统调用跟踪的瑞士军刀。掌握其核心选项,能让你从海量输出中快速定位问题。本节聚焦四个最常用的基础选项:-c(统计)、-e(过滤)、-o(输出文件)和 -p(附加进程)。
2.1 -c:系统调用统计模式
-c 选项将 strace 从逐条输出模式切换为汇总统计模式。它不打印每次调用的细节,而是在程序退出时输出一张统计表,包含每个系统调用的调用次数、总耗时、平均耗时、错误次数等信息。
适用场景:性能瓶颈分析、系统调用热点识别、对比不同实现方式的系统开销。
统计输出字段解析
| 字段 | 含义 | 调试价值 |
|---|---|---|
% time |
该调用耗时占总时间的百分比 | 快速定位最耗时的系统调用 |
seconds |
该调用累计耗时(秒) | 量化性能影响 |
usecs/call |
每次调用的平均微秒数 | 判断单次调用效率 |
calls |
调用次数 | 识别高频调用 |
errors |
返回错误的次数 | 发现异常行为 |
使用示例
# 统计 ls 命令的系统调用分布
strace -c ls /tmp
# 输出示例(简化):
# % time seconds usecs/call calls errors syscall
# ------ ----------- ----------- --------- --------- ----------------
# 45.23 0.002345 234 10 read
# 22.15 0.001148 115 10 write
# 12.67 0.000657 66 10 openat
# 8.34 0.000432 43 10 close
# 6.51 0.000337 34 10 fstat
# 5.10 0.000264 26 10 mmap
# ------ ----------- ----------- --------- --------- ----------------
# 100.00 0.005183 60 total
调试技巧:当
usecs/call 值异常偏高时(如 read 超过 1000 us),通常意味着 I/O 阻塞或磁盘性能问题。结合 -e trace=file 过滤文件相关调用,可以进一步缩小排查范围。
2.2 -e:系统调用过滤表达式
-e 选项是 strace 最强大的过滤机制。它允许你只跟踪感兴趣的系统调用类别或特定调用,大幅减少输出噪音。
过滤表达式语法
| 表达式 | 含义 | 示例 |
|---|---|---|
trace=file |
文件相关调用(open, read, write, close 等) | strace -e trace=file ls |
trace=process |
进程管理调用(fork, exec, exit 等) | strace -e trace=process ./app |
trace=network |
网络相关调用(socket, connect, send, recv 等) | strace -e trace=network curl http://example.com |
trace=signal |
信号相关调用(kill, signal, sigaction 等) | strace -e trace=signal ./daemon |
trace=desc |
文件描述符操作(dup, fcntl, poll 等) | strace -e trace=desc ./server |
trace=ipc |
进程间通信(shm, sem, msg 等) | strace -e trace=ipc ./ipc_app |
read=fd |
显示指定文件描述符的读取内容 | strace -e read=3 ./app |
write=fd |
显示指定文件描述符的写入内容 | strace -e write=1 ./app |
组合过滤与否定过滤
# 只跟踪文件相关调用,但排除 close 调用
strace -e trace=file -e trace=!close ls /tmp
# 同时跟踪文件和网络调用
strace -e trace=file,network curl http://example.com
# 跟踪所有调用,但排除 write 和 read(减少输出量)
strace -e trace=!write,read ./app
注意:过滤表达式中的
! 表示排除。排除 write 和 read 可以大幅减少输出,但可能错过 I/O 相关的性能问题。建议先不加过滤运行一次,确认问题范围后再针对性过滤。
2.3 -o:输出到文件
默认情况下,strace 将输出发送到 stderr。使用 -o 选项可以将输出重定向到指定文件,便于后续分析、搜索和保存。
基本用法
# 将跟踪输出保存到文件
strace -o /tmp/strace.log ls /tmp
# 查看输出文件
cat /tmp/strace.log | head -20
# 结合 -c 使用,将统计结果保存到文件
strace -c -o /tmp/strace_stat.log ls /tmp
文件输出最佳实践
| 场景 | 推荐做法 | 说明 |
|---|---|---|
| 长时间跟踪 | strace -o trace.log -p PID |
避免终端输出被淹没,文件可随时查看 |
| 对比分析 | strace -o before.log ./v1strace -o after.log ./v2 |
使用 diff 对比两个版本的调用差异 |
| 结合 grep 搜索 | strace -o trace.log ./app; grep "ENOENT" trace.log |
快速定位文件不存在等错误 |
| 分卷输出 | 使用 -o file -ff(多进程) |
每个子进程生成独立文件 |
调试技巧:使用
-o 结合 -e trace=file 和 grep,可以快速找出程序打开了哪些配置文件:strace -o /tmp/trace.log -e trace=file ./app; grep -E "open(at)?\(" /tmp/trace.log | grep -v "ENOENT"
2.4 -p:附加到运行中的进程
-p 选项允许 strace 附加到已经运行的进程,而不是启动新程序。这是调试线上服务、守护进程和长时间运行程序的关键功能。
基本用法
# 附加到 PID 为 1234 的进程
strace -p 1234
# 附加到多个进程
strace -p 1234 -p 5678
# 附加到进程并过滤输出
strace -p 1234 -e trace=network
# 附加到进程,统计模式
strace -p 1234 -c
# 附加到进程,输出到文件
strace -p 1234 -o /tmp/nginx_trace.log
附加进程的注意事项
- 权限要求:需要与目标进程相同的用户 ID 或 root 权限
- 性能影响:附加 strace 会使每个系统调用增加约 50-200 微秒的开销
- 信号影响:附加时会给目标进程发送
SIGSTOP,分离时发送SIGCONT - 分离方式:按
Ctrl+C或Ctrl+D分离,目标进程继续运行 - 单线程限制:默认只跟踪主线程,使用
-f跟踪子线程
生产环境警告:在生产服务器上对高并发进程(如数据库、Web 服务器)使用 strace -p 时,性能下降可能达到 10-100 倍。建议在以下情况使用:
1. 低峰期操作
2. 只过滤特定调用(如 -e trace=network)
3. 使用 -c 统计模式而非逐条输出
4. 设置超时时间,如
1. 低峰期操作
2. 只过滤特定调用(如 -e trace=network)
3. 使用 -c 统计模式而非逐条输出
4. 设置超时时间,如
timeout 10 strace -p PID
2.5 选项组合实战
实际调试中,这四个选项经常组合使用。以下是一些典型场景的完整命令:
# 场景1:分析 Nginx worker 进程的网络调用
strace -p $(pgrep -f 'nginx: worker') -e trace=network -o /tmp/nginx_net.log
# 场景2:统计 MySQL 查询相关的文件操作
strace -p $(pidof mysqld) -c -e trace=file -o /tmp/mysql_file_stat.log
# 场景3:跟踪新启动的进程,只输出错误调用
strace -e trace=!write,read -o /tmp/errors.log ./app 2>&1 | grep -E "= -1|ENOENT|EACCES"
# 场景4:长时间跟踪并自动分离(使用 timeout)
timeout 30 strace -p 1234 -e trace=file -o /tmp/30sec_trace.log
核心要点回顾:
• -c:统计模式,适合性能分析,不输出逐条调用
• -e:过滤表达式,减少输出噪音,支持组合和否定
• -o:输出到文件,便于保存和后续分析
• -p:附加到运行中进程,调试线上服务的关键
• 组合使用时,先加
• -c:统计模式,适合性能分析,不输出逐条调用
• -e:过滤表达式,减少输出噪音,支持组合和否定
• -o:输出到文件,便于保存和后续分析
• -p:附加到运行中进程,调试线上服务的关键
• 组合使用时,先加
-e 过滤,再加 -o 输出,最后加 -p 或程序名