strace 怎么用?一条命令看进程卡在哪个系统调用
答案:strace -p <PID> 实时打印目标进程的系统调用与信号;配合 -c 汇总统计、-f 跟随子进程、-e 过滤类别,就能定位"程序卡在哪、在做什么、为什么慢"。
常用姿势
bash
# 1. 跟踪一个新启动的命令
strace ls /tmp
# 2. 跟踪运行中的进程(最常见:程序卡住了)
strace -p <PID>
# 3. 跟随子进程(如服务 fork 出的 worker)
strace -f -p <PID>
# 4. 汇总统计:哪个系统调用次数多、耗时高
strace -c -p <PID> # Ctrl+C 后输出汇总表
# 5. 只看网络调用,避免刷屏
strace -e trace=network -p <PID>三步定位"卡在哪"
strace -p <PID>附加,等 1~2 秒;- 看输出最后一行停在哪个系统调用:
- 卡在
read/pread/fsync→ 等文件/网络 IO; - 卡在
futex/pthread_mutex→ 等锁; - 卡在
poll/epoll_wait/select→ 等事件,属于正常等待; - 卡在
connect/recvfrom→ 等网络对端;
- 卡在
- 若输出刷屏且总是同几个调用 → 用
-c统计,按耗时排序找瓶颈。
注意事项
- 性能开销大:strace 让每个 syscall 陷入 ptrace,程序会显著变慢,生产环境短时用;
- 会改变时序:跟踪本身会放大某些竞争问题;
- 内核线程看不到:strace 跟踪不了内核内部路径,那是
perf/bpftrace的领域。
深度入口
- strace 完整用法与输出解读:strace 使用指南
- 系统调用内部原理:系统调用
- 相关工具对比:工具选择指南
FAQ
Q: strace 怎么用? A: strace -p <PID> 跟踪运行中进程的系统调用;strace <命令> 跟踪新进程;-f 跟随子进程;-e trace=network 只跟踪网络调用。
Q: 程序卡住/无响应,怎么用 strace 定位? A: strace -p <PID> 看它停在哪个系统调用:若长期卡在 read 上说明等 IO,卡在 futex 说明等锁,卡在 poll/epoll 说明等事件。
Q: 怎么统计进程在哪些系统调用上花时间? A: strace -c -p <PID> 会汇总每个系统调用的次数与耗时,最耗时的调用就是瓶颈线索。
Q: strace 会不会让程序变慢很多? A: 会。strace 让每个系统调用都陷入 ptrace,性能开销可达数倍到数十倍,生产环境只适合短时诊断。
Q: 怎么只跟踪某类系统调用,避免刷屏? A: 用 -e 过滤,如 -e trace=network 只看网络、-e trace=file 只看文件、-e trace=open,close 只看指定调用。
Q: strace 输出里 read(3, "", 1024) 返回 0 是什么意思? A: 返回 0 表示读到 EOF(对端关闭或文件到末尾),程序通常在循环里读到 0 后退出或重试。
一句话总结:strace -p <PID> 看最后一行停在哪个系统调用,就知道进程在等 IO、等锁还是等事件——这是最快的"程序卡住"定位法。