直接用strace -f -p PID -T -tt附加到运行进程,实时查看带耗时和微秒时间戳的系统调用;高频场景需配合-e trace=...筛选关键调用,并用-ff -o file分离子进程日志。
直接用 strace 就行,但必须选对参数组合,否则要么看不到关键调用,要么日志爆炸无法定位。
怎么 attach 到正在运行的进程并实时看系统调用
最常见场景:服务卡住、CPU 占用高、响应变慢,你得立刻知道它在等什么。
- 用
ps aux | grep your_process或pgrep -f "your_process"先拿到 PID,比如是12345 - 执行
strace -p 12345 -T -tt:-T 显示每次系统调用耗时,-tt 打微秒级时间戳,能一眼看出哪次调用卡了 2 秒还是挂起不动 - 如果进程频繁 fork 子进程(比如 Nginx、PHP-FPM),漏掉子进程就等于漏掉真相 —— 必须加
-f,即strace -f -p 12345 -T -tt - 注意:
-f下输出会混杂多个 PID 的调用,别指望靠肉眼分清谁是谁;真要分离分析,得配合-ff -o trace.out,它会自动生成trace.out.12345、trace.out.12346等文件
怎么只关注特定类型系统调用(比如网络或文件)
全量跟踪日志动辄上万行,尤其高并发服务,不筛选根本没法读。
- 查网络问题?用
-e trace=connect,sendto,recvfrom,accept,避免被brk、mmap这类内存调用淹没 - 查文件加载失败?用
-e trace=open,openat,stat,fstat,再配合-s 256(默认只截 32 字节路径)看清完整文件名 - 想排除干扰?
-e trace=!mmap,mprotect,rt_sigreturn可跳过高频低信息量调用(注意 shell 里!要转义为\!,否则可能触发历史命令) - 别迷信
-e trace=file这类宏 —— 它实际展开的调用集版本间有差异,不同内核或 glibc 下行为可能不一致,显式列明更可靠
怎么统计哪个系统调用最耗时或最频繁
不是所有卡顿都来自单次长阻塞;也可能是百万次 read 调用累积成瓶颈。
CA.LA
第一款时尚产品在线设计平台,服装设计系统
下载
- 让程序跑完再出报告:
strace -c your_command,退出后显示汇总表,含 %time、seconds、calls、errors - 想边跑边看?用
-C(注意是大写 C),它会在 stdout 实时刷新统计,但会干扰程序原始输出,慎用于交互式命令 - 注意
-c统计的是“用户态进入内核再返回”的总开销,不包含纯用户态计算时间;如果看到epoll_wait占 95% 时间,大概率是空轮询或连接数配置不合理,不是内核 bug - 若程序本身不退出(如守护进程),
-c无效 —— 此时只能靠-T+ 人工采样,或改用perf trace补充分析
为什么 strace 有时显示 “Process detached” 就停了
这不是错误,是正常行为,但背后有关键细节容易被忽略。
-
strace默认以父进程身份跟踪目标进程,一旦目标进程 execve(比如 shell 执行新命令),旧进程结束、新进程诞生,strace 就自动 detach —— 这就是你看到 “Process detached” 的原因 - 想持续跟踪 exec 后的新进程?必须加
-f,它能让 strace 接着跟踪 fork/exec 链条上的所有后续进程 - 但
-f不等于万能:如果目标进程用vfork+exec(常见于 busybox 类精简工具),部分老版本 strace 会丢失跟踪,此时需加-F强制处理 vfork(不过现代内核和 strace 版本已基本默认兼容) - 还有一种情况:目标进程设置了
ptrace_scope为 1(Ubuntu/Debian 默认),普通用户无法 attach —— 此时会报Operation not permitted,得用sudo或临时改/proc/sys/kernel/yama/ptrace_scope
真正难的不是记住参数,而是从满屏 recvfrom(5, 、epoll_wait(、futex( 里快速识别出那个异常的返回值、超长耗时或重复失败模式 —— 这需要你对系统调用语义和常见错误码(比如 EAGAIN vs ETIMEDOUT)有肌肉记忆,而不是依赖工具自动标红。
