Strace 系统调用追踪教程
strace 是 Linux 上最常用的调试和诊断工具之一,它可以追踪进程执行的所有系统调用及接收的信号。当应用出现异常行为、启动失败或性能下降时,strace 往往是排查问题的第一选择。本文将系统讲解 strace 的各种用法和实战技巧。
一、安装 strace
# Ubuntu/Debian
apt update
apt install strace -y
# CentOS
yum install strace -y
# 验证安装
strace --version
二、基本用法
2.1 追踪命令执行
# 追踪命令的所有系统调用
strace ls -la /
# 追踪并显示时间戳
strace -t ls -la /
# 显示微秒精度的时间戳
strace -tt ls -la /
# 显示每个系统调用的耗时
strace -T ls -la /
# 输出到文件
strace -o trace.log ls -la /
2.2 追踪运行中的进程
# 附加到指定 PID
strace -p PID
# 同时追踪所有子线程
strace -f -p PID
# 追踪并统计
strace -c -p PID
2.3 过滤特定系统调用
# 只追踪文件相关调用
strace -e trace=file ls -la /
# 只追踪网络相关调用
strace -e trace=network curl http://example.com
# 只追踪进程管理调用
strace -e trace=process bash -c "ls | wc -l"
# 追踪特定的系统调用
strace -e trace=open,read,write,close cat /etc/passwd
# 追踪信号
strace -e signal=SIGTERM,SIGKILL -p PID
三、实战诊断场景
3.1 程序启动失败
# 追踪程序启动过程,查找缺失的文件或库
strace -f -e trace=file ./my-program 2>&1 | grep -i "no such file"
# 查找程序加载的共享库
strace -e trace=openat ./my-program 2>&1 | grep "\.so"
# 查找程序读取的配置文件
strace -e trace=openat,access ./my-program 2>&1 | grep -E "\.(conf|cfg|ini|yaml|json)"
3.2 性能瓶颈定位
# 统计各系统调用的次数和耗时
strace -c -p PID -e trace=all
# 找出耗时最长的系统调用
strace -T -p PID 2>&1 | awk '{print $NF, $0}' | sort -rn | head -20
# 找出 I/O 等待
strace -T -e trace=read,write,pread64,pwrite64 -p PID
strace 的 -c 选项会输出统计摘要,包括每种系统调用的次数、总耗时和出错次数,是快速定位瓶颈的好方法。
3.3 网络问题诊断
# 追踪网络连接
strace -e trace=network -f -p PID
# 查看 DNS 解析过程
strace -e trace=network,open curl http://example.com 2>&1 | grep -E "connect|sendto|recvfrom"
# 查看连接超时
strace -e trace=connect -T curl http://slow-server.com
3.4 文件权限问题
# 追踪权限检查
strace -e trace=access,openat ./my-program 2>&1 | grep "EACCES\|EPERM"
# 查找程序访问了哪些文件
strace -e trace=openat -f ./my-program 2>&1 | grep -v "ENOENT"
四、高级技巧
4.1 字符串输出长度
# 默认字符串截断为 32 字节,增加到 1024
strace -s 1024 -e trace=read,write -p PID
# 显示完整路径
strace -y -e trace=file ls -la /
4.2 多进程追踪
# 追踪所有子进程
strace -f -o trace.log ./my-daemon
# 每个进程输出到单独文件
strace -ff -o trace ./my-daemon
# 会生成 trace.PID1, trace.PID2 等文件
4.3 条件追踪
# 只显示返回错误的系统调用
strace -Z -e trace=all ./my-program
# 只显示成功的系统调用
strace -z -e trace=all ./my-program
# 注入故障(测试错误处理)
strace -e inject=open:error=ENOENT:when=3 ./my-program
五、Nginx 诊断实例
# 查看 Nginx worker 处理请求时的系统调用
NGINX_PID=$(pgrep -f "nginx: worker" | head -1)
strace -f -e trace=network,read,write -p $NGINX_PID -T 2>&1 | head -100
# 统计 Nginx 的系统调用分布
strace -c -f -p $NGINX_PID -e trace=all &
sleep 30
kill %1
# 查找 Nginx 读取的配置文件
strace -e trace=openat nginx -t 2>&1 | grep "\.conf"
六、MySQL 诊断实例
# 追踪 MySQL 的 I/O 操作
MYSQL_PID=$(pgrep -f "mysqld" | head -1)
strace -e trace=read,write,pread64,pwrite64 -T -p $MYSQL_PID 2>&1 | head -50
# 查看 MySQL 打开的文件
strace -e trace=openat -p $MYSQL_PID 2>&1 | grep -v ENOENT
七、注意事项
- 性能影响:strace 使用 ptrace 系统调用,会显著降低被追踪进程的性能(通常 2-10 倍的开销),生产环境慎用。
- 安全考虑:strace 输出可能包含敏感信息(密码、密钥等),注意保护输出文件。
- 替代方案:对于生产环境,建议使用开销更低的 BPFtrace 或 perf。
- 容器环境:Docker 容器中使用 strace 需要添加
--cap-add SYS_PTRACE参数。
总结
strace 是 Linux 系统管理和应用调试的瑞士军刀,简单直接,几乎可以诊断任何系统级问题。对于更高级的追踪需求,可以使用 BPFtrace。CPU 层面的性能分析推荐 perf 和 火焰图。选购搬瓦工 VPS 请查看 全部方案,购买时使用优惠码 NODESEEK2026 可享受 6.77% 的折扣,通过 bwh81.net 访问官网。