strace -p PID卡住不动通常因目标进程处于D状态或权限不足;Permission denied需检查ptrace_scope或容器CAP_SYS_PTRACE;过滤关键调用应使用-e trace=指定系统调用类型,并配合-z、-T、-s等参数提升可读性。

直接用 strace -p PID 就能实时看到进程在跟内核“要什么”,但多数卡顿、权限失败或空输出,不是命令写错了,而是环境或参数没对上。
strace -p PID 为什么卡住不动?
执行 strace -p 12345 后终端无响应,不是 strace 崩了,大概率是目标进程正处在 D 状态(不可中断睡眠),比如卡在磁盘 I/O 或内核锁里。
- 先运行
ps -o pid,stat,comm -p 12345,看STAT列是否含D—— 如果是,进程本身已死锁,strace 只是如实同步阻塞 - 别反复按
Ctrl+C,多次中断可能让 strace 进入异常状态,后续跟踪失效 - 想降低干扰又保留耗时信息,改用
strace -p 12345 -e trace=none -T - 真要强制 detach,换终端执行
kill -SIGUSR1 $(pgrep -f "strace.*12345")(仅部分版本支持)
Permission denied: Operation not permitted 怎么办?
普通用户执行 strace -p PID 报这个错,90% 是被内核 ptrace_scope 拦了,尤其 Ubuntu/Debian 默认设为 1。
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
- 检查当前限制:
cat /proc/sys/kernel/yama/ptrace_scope,值为1表示非 root 不能 trace 其他用户进程 - 临时放开(重启失效):
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope - 容器内运行时,需确认容器启动加了
--cap-add=SYS_PTRACE,否则即使 root 也 attach 失败 - seccomp profile 也可能禁用
ptrace,这时得改容器配置或换调试方式
怎么过滤出真正有用的调用,而不是刷屏?
默认输出全是 open/read/mmap,关键线索容易淹没。用 -e trace= 锁定行为类型最有效。
- 只看文件操作:
strace -e trace=open,openat,read,write,close -p 12345 - 只看网络行为:
strace -e trace=socket,connect,sendto,recvfrom -p 12345 - 只抓失败项(返回
= -1):strace -e trace=all -z -p 12345 - 组合使用更准:
strace -e trace=openat,connect -z -s 256 -T -p 12345,其中-s 256防字符串截断,-T显示耗时
子进程、日志和错误码怎么看?
很多程序 fork 出子进程干活,不加 -f 就等于只盯主进程门口,里面干啥完全不知道。
- 必须加
-f才能看到子进程调用:strace -f -p 12345 - 日志太大要保存分析:
strace -o /tmp/trace.log -f -s 256 -T -p 12345 - 失败行格式是
openat(...)= -1 ENOENT (No such file or directory),括号里是可读错误名,ENOENT对应缺失路径,EACCES是权限拒绝 -
AT_FDCWD不是路径,是“当前工作目录”的 fd 值;O_RDONLY|O_CLOEXEC是 flag 组合,strace 自动反解,但查内核源码时得知道原始数值
真正难的不是跑通 strace,而是从几百行输出里识别哪一行是根因——比如某个 openat 返回 -1 ENOENT,后面所有基于它的 read(3, ...) 都会失败,但 strace 不会自动标红提醒你这条线断了。

















