PHP 怎么strace追踪

wen PHP项目 1

本文目录导读:

PHP 怎么strace追踪

  1. 基本 strace 用法
  2. 常用 strace 参数
  3. 性能分析
  4. 实际调试案例
  5. 高级技巧
  6. 输出分析技巧
  7. 注意事项
  8. 替代/辅助工具
  9. Docker/容器环境

在 PHP 开发中,strace 是排查问题的强大工具,以下是详细的追踪方法和技巧:

基本 strace 用法

追踪 CLI 脚本

# 直接追踪 PHP 脚本执行
strace php /path/to/script.php
# 追踪并保存到文件
strace -o /tmp/php_trace.log php /path/to/script.php
# 追踪并显示时间戳
strace -t -o /tmp/php_trace.log php script.php
# 追踪并显示相对时间
strace -r -o /tmp/php_trace.log php script.php

追踪 Web 请求(PHP-FPM)

# 找到 PHP-FPM 进程
ps aux | grep php-fpm
# 附加到已运行的进程
strace -p <PID>
# 追踪所有 PHP-FPM 进程
strace -f -o /tmp/php-fpm_trace.log php-fpm

常用 strace 参数

# 追踪系统调用并显示参数
strace -v php script.php
# 显示字符串参数(限制长度)
strace -s 256 php script.php
# 追踪特定系统调用
strace -e trace=open,read,write php script.php
# 追踪文件相关操作
strace -e trace=file php script.php
# 追踪网络相关操作
strace -e trace=network php script.php
# 追踪内存分配
strace -e trace=memory php script.php
# 追踪子进程
strace -f php script.php
# 统计系统调用
strace -c php script.php
# 显示时间戳和相对时间
strace -ttt -r php script.php

性能分析

# 查看系统调用时间统计
strace -c -T php script.php
# 查看耗时超过指定时间(秒)的调用
strace -T -e trace=all -o trace.log php script.php
# 然后分析 trace.log 中 TIME 字段
# 显示每个线程的系统调用
strace -f -tt -T -o /tmp/trace.log php script.php

实际调试案例

案例1:查找文件找不到问题

strace -e trace=open,stat,access php script.php 2>&1 | grep "ENOENT"
# 或
strace -e file php script.php 2>&1 | grep "No such file"

案例2:分析数据库连接问题

strace -e trace=network,connect,sendto,recvfrom php script.php

案例3:分析慢请求

# 找出耗时最长的系统调用
strace -f -T -o /tmp/trace.log php slow_script.php
# 然后查看 TIME 列
awk '{if ($NF ~ /^[0-9.]+$/) print $NF, $0}' /tmp/trace.log | sort -rn | head -20

案例4:追踪 PHP-FPM 特定请求

# 监控 PHP-FPM,显示每次请求的文件操作
strace -p $(pgrep -f "php-fpm: master") -f -e trace=file
# 通过请求参数过滤
strace -e trace=open,read -s 256 -o /tmp/web_trace.log \
  -p $(pgrep -f "php-fpm: pool www" | head -1)

高级技巧

条件过滤

# 只追踪失败的调用
strace -e trace=open -e fault=open php script.php
# 显示文件描述符使用
strace -e trace=close,read,write php script.php 2>&1 | grep "EBADF"

同时追踪多个参数

# 组合多个追踪条件
strace -e trace=open,read,write,connect,accept \
       -e signal=all \
       -o /tmp/debug.log \
       php script.php

生成调用图

# 使用 -y 显示文件描述符对应的文件路径
strace -y -e trace=open,read,write php script.php

输出分析技巧

# 查看打开的文件
grep "open(" /tmp/trace.log
# 查看网络连接
grep -E "connect|accept|socket" /tmp/trace.log
# 查找错误
grep -E "EACCES|EPERM|ENOENT|ECONNREFUSED" /tmp/trace.log
# 提取 PHP 执行的系统调用摘要
strace -c php script.php 2>&1
# 统计各类系统调用次数
grep -o '^[a-z_]*' /tmp/trace.log | sort | uniq -c | sort -rn

注意事项

  1. 权限问题:需要 root 或与目标进程相同用户权限
  2. 性能影响:会增加显著开销,生产环境谨慎使用
  3. 内存占用:日志文件可能很大,注意磁盘空间
  4. 时间戳精度:使用 -ttt 获取微秒级时间戳

替代/辅助工具

# ltrace 追踪库调用
ltrace php script.php
# 网络抓包
tcpdump -i any -s 0 port 3306
# PHP 内置调试扩展
php -d error_reporting=E_ALL -d display_errors=1 script.php
# Xdebug 追踪
XDEBUG_TRACE=1 php script.php

Docker/容器环境

# 容器内追踪
docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined \
  -it php:latest strace php script.php
# 或者
docker exec -it container_name strace -p $(pgrep -f "php-fpm")

这些技巧能帮助你快速定位 PHP 应用中的文件访问、网络请求、内存分配等各类问题,记得根据实际场景选择合适的追踪选项,避免过多无关信息。

抱歉,评论功能暂时关闭!