strace是定位卡死、崩溃、读写失败等故障的第一响应工具;可attach到运行进程(如strace -p PID -f -e trace=network,io -s 256 -T),需加-f跟踪子进程,-e显式过滤关键调用,-o保存完整日志。

strace 不是“看看调用有哪些”的浏览工具,它是定位卡死、崩溃、读写失败、连接拒绝等真实故障的第一响应手段。只要程序行为异常但日志空白,strace 往往三行内就暴露根因——比如 openat(...) 返回 ENOENT,或 connect(...) 卡在 ECONNREFUSED。
怎么 attach 到正在跑的进程(不重启)
这是最常用也最容易出错的场景:服务变慢、请求堆积、CPU 空转,但你不能停它。
- 先用
pgrep -f "redis-server"或pidof nginx拿到 PID,别靠ps aux | grep手动数,容易错位 - 执行
strace -p 12345 -f -e trace=network,io -s 256 -T,重点在:-f跟子进程(worker)、-e trace=network,io避免被clock_gettime淹没、-s 256防路径截断(默认只显示前 32 字符) - 按
Ctrl+C中断后,最后一屏往往就是问题现场;如果输出太快,加-o /tmp/trace.log保存再查 - 常见坑:没加
-e trace=...就直接跑,结果满屏read(0, ...)和write(1, ...),根本看不出哪次connect失败了
为什么启动时跟踪必须加 -f
几乎所有后台服务(nginx、redis、java -jar)都会 fork 出子进程处理请求。不加 -f,你只看到主进程初始化,完全看不到 worker 在干啥。
-
strace ./myapp→ 只跟踪主进程,子进程系统调用全丢失 -
strace -f ./myapp→ 主进程 + 所有 fork 出的子进程都被捕获 - 更进一步,用
strace -ff -o trace.log ./myapp,会生成trace.log.1234、trace.log.1235等独立文件,按 PID 区分,方便逐个排查 - 注意:某些容器环境(如
docker run --cap-add=SYS_PTRACE)需显式授权,否则strace -f会报Operation not permitted
过滤 open/connect 等关键调用总失败?检查集合名和版本
strace -e trace=file,network 看起来合理,但在 CentOS 7 或旧版 strace 上很可能漏掉 openat 和 accept4——而现代程序(尤其容器内)几乎只用 openat。
- 安全写法是显式列举:
-e trace=open,openat,read,write,connect,accept,accept4,sendto,recvfrom -
file集合在较新内核(5.4+)和strace5.10+ 才真正包含openat;老系统得手动补 - UDP 流量不会出现在
connect里,得加sendto/recvfrom;TCP 连接超时是ETIMEDOUT,不是EAGAIN,别混淆 - 验证是否生效:运行
strace -e trace=openat ls /,看输出里有没有openat(AT_FDCWD, "/", ...)——没有就说明过滤没起作用
保存日志别用重定向,-o 才可靠
strace ./app > log.txt 2>&1 表面可行,但会丢掉关键错误上下文:部分系统调用失败信息(如权限拒绝)走 stderr,且 strace 自身的调试提示(如 ptrace 权限警告)也被吞掉。
- 正确做法永远用
-o trace.log:它把 stdout 和 stderr 统一归入日志,且保持时间戳、耗时、文件描述符路径(-y)等元信息完整 - 加
-tt -T -y一起用:strace -tt -T -y -o trace.log -f ./app,输出形如14:22:03.123456 openat(AT_FDCWD, "/etc/my.conf", ...) = -1 ENOENT (No such file or directory) - 大日志要可搜:跑完立刻
grep -E "(EACCES|ENOENT|ECONN|ETIMEDOUT)" trace.log,90% 的配置/网络/权限问题当场定位
strace 最容易被忽略的其实是时机——不是“能不能抓”,而是“在哪一刻抓”。卡死时 attach,比等它崩了再翻日志有效十倍;启动失败时用 -f 全程跟踪,比反复猜配置路径省两小时。参数组合可以记不住,但 -f、-e trace=...、-o 这三个必须条件反射般带上。

















