使用 strace 跟踪 PHP 进程延迟的核心在于附加到目标进程 PID,重点监控耗时较长的系统调用。通过 `strace -T -tt -p
Linux 系统利用 Strace 跟踪进程系统调用定位程序故障方法
是 Linux 下直接有效的系统调用跟踪工具,可实时捕获调用参数、返回值及错误码,用于快速定位卡死、崩溃、读写失败等故障;支持附加运行中进程或启动时全程跟踪,配合 -f、-e、-s、-T、-y 等选项提升排查效率。strace 是 Linux 下最直接、最有效的系统调用跟踪工具,能实时捕获进程执行过程中发起的所有系统调用及其参数、返回值和错误码。当程序出现“卡死”“崩溃”“读写失败”“权限拒绝”或“找不到文件”等现象,而日志又不明确时,strace 往往能一眼定位根本原因——比如打开某个配置文件失败、连接特定端口被拒绝、等待不存在的信号量、或陷入无限 poll/select 循环。快速启动:跟踪正在运行的进程 无需重启程序,可直接附加到已有进程:先用 ps aux | grep 程序名或 pidof 程序名获取 PID 执行 strace -p PID 查看实时系统调用流 (按 Ctrl+C 停止) 加-e trace=openat,open,read,write,connect,close 可聚焦关键调用,减少干扰 加-s 256 显示更长的字符串参数 (默认只截取 32 字符) 精准复现:启动时全程跟踪新进程 对启动即出错的程序 (如服务无法初始化),推荐从源头跟踪:strace -f -o trace.log ./myapp --config /etc/myapp.conf -f 跟踪子进程 (重要!尤其涉及 fork/exec 的服务) -o trace.log 将输出保存到文件,便于搜索和分析 运行后立即查看 log:用 grep -E "(ENO|EACCES|ENOT|ECONN)" trace.log 快速筛选错误 识别典型故障模式 观察 strace 输出时,重点关注以下线索:openat(AT_FDCWD, "/etc/myapp.conf", O_RDONLY) = -1 ENOENT (No such file or directory)→ 配置路径错误或文件缺失 connect(3, {sa_family=AF_INET, sin_port=htons(6379), }, 16) = -1 ECONNREFUSED (Connection refused)→ 后端服务未启动或地址不对 read(4, "", 4096) = 0 后反复出现 poll(, POLLIN, ) = 1→ 可能已读到 EOF 却未正确处理退出逻辑 stat("/proc/self/fd/3", ) = -1 EBADF (Bad file descriptor)→ 文件描述符已被关闭却继续使用 进阶技巧提升排查效率 避免信息过载,让 strace 输出更有针对性:用-T 显示每次系统调用耗时,快速发现性能瓶颈 (如某次 open 耗时 3 秒,可能挂载点卡住) 用-y 显示文件描述符对应的实际路径 (如 read(3, )) 用-P /path/to/file 只跟踪对指定路径的访问 (适合排查文件级问题) 结合 lsof -p PID 和/proc/PID/fd/查看当前打开的资源,与 strace 对照验证 strace strace 是 Linux 下直接有效的系统调用跟踪工具,可实时捕获调用参数、(2026 年 3 月 24 日的资料)
怎么在 Linux 利用 Strace 跟踪 Web 服务系统调用超时问题
strace 不能直接捕获“超时”这类逻辑错误,它只记录系统调用的发起、返回及耗时,不理解业务语义;超时是应用层或库函数触发的控制流跳转,strace 仅能观察其依赖的系统调用是否阻塞,如 recvfrom 长时间未返回、epoll_wait 持续阻塞等。strace 能否直接捕获“超时”这类逻辑错误 不能。strace 只记录系统调用的发起、返回及耗时,不理解业务语义。所谓“超时”,通常是应用层 (如 Nginx 的 proxy_read_timeout) 或库函数 (如 curl_easy_setopt 设置的 CURLOPT_TIMEOUT) 触发的控制流跳转,strace 看不到这些判断逻辑,只能看到其背后依赖的系统调用是否卡住——比如 recvfrom 长时间没返回、epoll_wait 一直阻塞、或 connect 返回 EINPROGRESS 后迟迟不就绪。关键要跟踪哪些系统调用和信号 Web 服务超时问题通常集中在 I/O 等待环节,优先关注:connect:连接建立是否卡在三次握手 (如 SYN_SENT 状态下无响应) recvfrom/read:后端响应迟迟未到达,或客户端读取缓慢 sendto/write:发送缓冲区满、对端接收窗口为 0 导致阻塞 epoll_wait/poll/select:事件循环卡住,说明没有就绪的 fd(可能因上游未发数据、下游未消费) clock_gettime 和 gettimeofday:确认超时判断是否由高精度计时器触发 (常配合 alarm 或 timerfd_create) sigreturn 和 rt_sigprocmask:检查是否被 SIGALRM 中断,这是很多超时实现的底层机制 实际抓取命令怎么写才不漏关键信息 直接对主进程 strace -p PID 往往不够——Web 服务多线程/多进程,主线程可能只做 accept,真正处理请求的是 worker 进程。必须跟踪到具体处理请求的上下文:iSlide PPT DeepSeek AI 加持,输入主题生成专业 PPT,支持 Word/PDF 等 45 种文档导入,职场汇报、教学提案轻松搞定 对 Nginx:先 ps aux | grep nginx 找出 worker 进程 PID,再 strace -T -tt -e trace=connect,recvfrom,read,sendto,write,epoll_wait,poll,select,clock_gettime,gettimeofday,sigreturn -p
strace 调试 php,strace ltrace 调试 php
看到这两次系统调用之间的延时非常大,却并不知道干了什么?一筹莫展了,幸好,Linux 下的调试利器除了 strace 还有 ltrace(当然还有 dtrace,ptrace,不在本文讨论范围了,略去)。引用:strace 用来 跟踪一个进程的系统调用或信号产生的情况,而 ltrace 用来 跟踪进程调用库函数的情况 (viaIBM developerworks)。为了排除干扰因素,将$x 直接赋值为 array("0″,"1″,"2″,……) 的形式,避免过多的 malloc 调用影响结果。执行 shell$ ltrace -c /usr/local/php/bin/php test.php 看到库函数__strtol_internal 的调用非常之频繁,达到了 94%,太夸张了,然后我又查了一下这个库函数__strtol_internal 是干嘛的,原来是 strtol 的别名,简单的说就是把字符串转换成长整形,可以猜测 PHP 引擎已经检测到这是一个字符串型的数字,所以期望将他们转换成长整型来比较,这个转换过程中消耗了太多时间,我们再次执行:shell$ ltrace -e "__strtol_internal" /usr/local/php/bin/php test.php 可以轻松抓到大量下图这样的调用,到此,问题找到了,in_array 这种松比较,会将两个字符型数字串先转换为长整型再进行比较,却不知性能就耗在这上面了。知道了症结所在,我们解决的办法就很多了,最简单的就是为 in_array 加第三个参数为 true,即变为严格比较,同时还要比较类型,这样避免了 PHP 自作聪明的转换类型,跑起来果然快多了,代码如下:$y="1800"; $x = array(); for(𝑗=0;j=0;j<2000;$j++){ x[]= "{x[]= "{j}"; } for(𝑖=0;i=0;i<3000;$i++){ if(in_array(𝑦,y,x,true)){ continue(消息于 2021 年 3 月 10 日发布)
php 跟踪系统调用,使用 strace 命令跟踪系统调用
strace 能做什么?基于特定的系统调用或系统调用组进行过滤 通过统计特定系统调用的使用次数,所花费的时间,以及成功和错误的数量来分析系统调用的使用。它跟踪发送到进程的信号。通过 pid 附加到任何正在运行的进程。调试性能问题,查看系统调用的频率,找出耗时的程序段 查看程序读取的是哪些文件从而定位比如配置文件加载错误问题 查看某个 php 脚本长时间运行“假死”情况 当程序出现"Out of memory"时被系统发出的 SIGKILL 信息所 kill 另外因为 strace 拿到的是系统调用相关信息,一般也即是 IO 操作信息,这个对于排查比如 cpu 占用 100% 问题是无能为力的。这个时候就可以使用 GDB 工具了。(该信息的时间戳是 2021 年 4 月 2 日)
FAQ
strace 会影响 PHP 进程性能吗?
会,strace 会导致被跟踪进程显著变慢,生产环境慎用。
如何只跟踪网络相关的系统调用?
使用 -e trace=network 参数。
怎么查看系统调用的耗时?
使用 -T 参数。