登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  linux

Linux strace -f 跟踪子进程时如何缩小输出

来源:17golang原创

时间:2026-09-15 08:00:29 149浏览 收藏

Linux 上用 strace -f 排查程序时,输出突然变得很长,通常不是子进程“失控”,而是你同时看到了父进程和所有后代进程的全部系统调用。缩小输出要分层做:先用 -e trace=... 限制调用类别,再用 -P 限制路径;需要整理多进程日志时,再加 -o-ff-qq。每次只加一个筛选条件,才知道究竟隐藏了什么。

排障时先保留 -f,不要一上来删掉子进程;优先收窄“看哪些调用”和“看哪个路径”,最后才处理输出文件和参数长度。过滤后的空白只能说明“没有留下匹配项”,不能直接证明调用没有发生。
要点速览
  • -f 负责跟踪子进程,-e trace=... 负责按系统调用类别过滤,两者解决的是不同问题。
  • -P /path 可以把观察范围收窄到路径;-o trace -ff 则把不同 PID 的输出拆开,便于定位。
  • 先用宽过滤建立基线,再逐项增加条件,并保留返回值,避免把“被隐藏”误判成“没执行”。

先用过滤器控制跟踪范围

-f 会让 strace 继续跟踪由当前进程创建或派生出来的进程,但它不会替你判断哪些调用重要。若问题是“子进程到底打开了哪些配置文件”,可以先只保留文件相关调用:

# 保留父子进程关系,只观察文件相关系统调用
strace -f -e trace=file -- ./worker

# 再把目标路径限制在应用配置目录;示例路径请替换为实际目录
strace -f -e trace=file -P /srv/app/config -- ./worker

-e trace=file 是调用集合过滤,-P 是路径过滤;它们不是“只跟踪某个 PID”的替代品。若过滤后没有输出,先撤掉 -P 看宽范围结果,再判断是路径不匹配还是程序没有走文件调用。

strace -f 使用系统调用和路径过滤的原创操作示意图
图1:strace 过滤器的操作示意图,先保留子进程,再把观察范围收窄到文件相关调用。

用文件和 PID 维度整理结果

多进程同时向标准错误输出时,父子进程的行会交错。可以把输出写入文件;加上 -ff 后,strace 会按进程拆分输出文件,文件名会带上对应 PID。这样更适合回答“是哪一个子进程返回了 ENOENT”这类问题:

# 把跟踪写入文件,并按 PID 拆分;-qq 减少附加提示行
strace -f -o trace -ff -qq -- ./worker

# 只查看各 PID 文件中的关键调用和返回值
rg 'execve|openat|read|ENOENT' trace.*

这里的 -ff 解决的是文件组织,不是过滤;仍然会记录很多调用。若只想看某个目标目录,可把它与上一节的 -e trace=file -P /srv/app/config 组合使用。-qq 只减少提示噪声,不会替你筛选系统调用。

参数作用适合回答
-f跟踪派生进程子进程是否参与
-e trace=...按调用类别筛选只看文件、网络或进程调用
-P按路径筛选谁访问了某个文件或目录
-o ... -ff按 PID 整理输出哪一个进程产生了结果
-s调整字符串显示长度参数被截断时补足上下文
按 PID 拆分 strace 输出并保留返回值的原创结果示意图
图2:多进程输出的结果示意图,按 PID 拆分文件后更容易定位子进程的目标调用。

按问题调整参数细节

如果真正的问题是“文件名或环境变量被截断”,再调整 -s,例如 -s 256;它改变字符串显示长度,不会减少系统调用数量。只想看调用统计时可以使用 -c,但统计模式适合找频率和耗时概况,不适合还原某一次调用的参数与返回值。

# 需要看较长路径或参数时提高字符串显示长度
strace -f -s 256 -e trace=file -- ./worker

# 只做系统调用汇总;它不是逐行跟踪日志
strace -f -c -- ./worker

不要同时堆上十几个选项再解释结果。推荐顺序是:无路径限制的 -e trace=file 建基线;加入 -P;输出变乱时加入 -o -ff;参数缺信息时才加 -s;需要统计时另跑一次 -c

验证筛选没有把关键调用藏掉

最容易误判的场景是:加了 -P 后没有结果,就认定程序没有访问目标文件。更稳妥的检查是逐层撤销条件,并记录每一步的观察范围:

  1. 先运行 strace -f -e trace=file,确认子进程确实出现在输出中。
  2. 再加 -P /目标路径,比较是否只剩目标路径相关行。
  3. 再改用 -o trace -ff,按 trace.PID 逐个查看,并关注 = 0= -1 ENOENT 等返回值。
  4. 若参数仍不完整,只增加 -s;不要用更强的过滤器掩盖上下文。

最后把“没有匹配输出”和“调用返回成功”分开记录。strace 只能展示被它捕获并保留下来的系统调用;过滤条件越窄,越需要回到宽范围基线复核。

常见问题

为什么用了 -f 还是看不到子进程的关键调用?

可能是后续的 -e-P 把调用过滤掉了,也可能子进程很快执行了 execve。先去掉路径过滤,保留 -f -e trace=process 或宽范围基线,再按 PID 回看。

-ff-f 有什么区别?

-f 决定是否跟踪派生进程;-ff 在此基础上把每个进程的输出写到独立文件。它们分别控制“跟谁”和“怎么整理输出”。

输出太长时只用 -qq 可以吗?

不行。-qq 主要减少附加提示,不能替代系统调用或路径过滤。应先使用 -e-P 收窄观察对象,再按需要用 -o -ff 整理文件。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>