本文目录导读:

在 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
注意事项
- 权限问题:需要 root 或与目标进程相同用户权限
- 性能影响:会增加显著开销,生产环境谨慎使用
- 内存占用:日志文件可能很大,注意磁盘空间
- 时间戳精度:使用
-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 应用中的文件访问、网络请求、内存分配等各类问题,记得根据实际场景选择合适的追踪选项,避免过多无关信息。