有关PHP的DEBUG一点想法

环境构建
# 创建网络[默认bridge]
docker network create nginx-php 

# 创建php容器
docker run -d -p 9000:9000 -v E:\MonkeyCode\local\php:/data/projects --name dev-php-v7.3 --network nginx-php php:7.3-fpm-alpine

# 创建nginx容器
docker run -d -p 8000-8080:8000-8080 -v E:\MonkeyCode\local\php:/data/projects --name dev-nginx-latest --network nginx-php nginx:latest
# nginx配置nginx注意事项
1. 在location节点外定义项目根目录;
2. 调整变量 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name
3. 注意核对 fastcgi_pass php-ip:port[fpm]
PHP安装XDebug扩展
wget https://pecl.php.net/get/xdebug-3.0.4.tgz
tar -zxf xdebug-3.0.4.tgz
docker-php-source extract
mv xdebug-3.0.4 /usr/src/php/etc/xdebug
docker-php-ext-install xdebug

# 查看扩展
php --ri xdebug
调整XDebug配置
; vi /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini

zend_extension="xdebug.so"
xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_host=host.docker.internal
xdebug.client_port=9001
xdebug.idekey=www

; 配置参考 https://xdebug.org/docs/all_settings
调整IDE配置
File => Settings => PHP => Debug
Xdebug port 和 xdebug.client_port保持一致即可

File => Settings => PHP => Server
Add Server
host 站点(ip/域名) port 站点端口 Debugger XDebug
# 我这里是docker, 必须要配置路径映射
file://E:/MonkeyCode/local/php/test => /data/projects/test[这是项目在容器中绝对路径]

设置 run/debug configurations
添加一个 php-remote-debug, IDE key 和 xdebug.idekey保持一致即可
然后 start listenings 就类似电话那个icon, 点击激活
最后 run/debug 即可

访问项目时, 地址加上XDEBUG_SESSION_START=idekey[我这里配置的www]
原理分析

为分析 XDebugPHP 的行为, 先来看下关闭 Debug 下表现, 为了调试方便, 我们先将 php-fpmwork proccess 调整为一个, 主要修改 /usr/local/php/73/etc/php-fpm.d/www.conf 的如下配置:

pm = static
pm.max_children = 1
; 保存后, 重启php-fpm, 我这里使用sudo systemctl restart php-fpm73即可
; 可使用 ps aux|grep php-fpm|grep -v color|grep -v master|wc -l 验证, 应输出1

这里还要补充一个命令strace , 能够记录和解析进程的系统调用以及接收到的信号值, 更多可参考 strace官网.

Debug 模式

xdebug.mode = off

大致流程: 请求进入创建fd => 读取数据 => 解析目标 => 执行(暂时没有看到) => 输出数据 => 关闭fd => 等待下轮请求.

sudo strace -tt -T -v -s 1024 -p 4856
# -tt 在每行输出的前面, 显示毫秒级别的时间
# -T 显示每次系统调用所花费的时间
# -v 对于某些相关调用, 把完整的环境变量, 文件stat结构等输出
# -s 当系统调用的某个参数是字符串时, 最多输出指定长度的内容, 默认32个字节
# 指定要跟踪的进程pid, 这里的4856, 是当前机器的php-fpm work proccess的进程id
strace: Process 4856 attached
09:08:15.298419 accept(8,
# SOCKET accept(int sockfd[套接字描述符], struct sockaddr *addr, socklen_t *addrlen);

打开浏览器键入 http://127.0.0.1:85/index.php , 监听响应如下:

09:08:15.298419 accept(8, {sa_family=AF_UNIX}, [112->2]) = 3 <157.450188>
# 请求进入, 创建对应fd
09:10:52.749787 poll([{fd=3, events=POLLIN}], 1, 5000) = 1 ([{fd=3, revents=POLLIN}]) <0.000037>
# 监听fd, 等待响应
09:10:52.750053 times({tms_utime=0, tms_stime=0, tms_cutime=0, tms_cstime=0}) = 1718163427 <0.000117>
# 初始时间标记
09:10:52.750407 read(3, "\1\1\0\1\0\10\0\0", 8) = 8 <0.000119>
# 从fd读取8字节数据, 疑似cgi标记头参数
09:10:52.750793 read(3, "\0\1\0\0\0\0\0\0", 8) = 8 <0.000083>
# 从fd读取8字节数据, 疑似cgi标记头参数
09:10:52.751079 read(3, "\1\4\0\1\4\330\0\0", 8) = 8 <0.000086>
# 从fd读取8字节数据, 疑似cgi标记头参数
09:10:52.751362 read(3, "\17/SCRIPT_FILENAME/home/speauty/PhpstormProjects/XDebug/index.php\t\0PATH_INFO\17%PATH_TRANSLATED/home/speauty/PhpstormProjects/XDebug\f\32QUERY_STRINGXDEBUG_SESSION_START=10503\16\3REQUEST_METHODGET\f\0CONTENT_TYPE\16\0CONTENT_LENGTH\v\nSCRIPT_NAME/index.php\v%REQUEST_URI/index.php?XDEBUG_SESSION_START=10503\f\nDOCUMENT_URI/index.php\r%DOCUMENT_ROOT/home/speauty/PhpstormProjects/XDebug\17\10SERVER_PROTOCOLHTTP/1.1\16\4REQUEST_SCHEMEhttp\21\7GATEWAY_INTERFACECGI/1.1\17\fSERVER_SOFTWAREnginx/1.18.0\v\tREMOTE_ADDR127.0.0.1\v\5REMOTE_PORT57778\v\tSERVER_ADDR127.0.0.1\v\2SERVER_PORT85\v\20SERVER_NAMEwww.xdebug.local\17\3REDIRECT_STATUS200\t\fHTTP_HOST127.0.0.1:85\17\nHTTP_CONNECTIONkeep-alive\22\tHTTP_CACHE_CONTROLmax-age=0\16(HTTP_SEC_CH_UA\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"90\"\25\2HTTP_SEC_CH_UA_MOBILE?0\36\1HTTP_UPGRADE_INSECURE_REQUESTS1\17iHTTP_USER_AGENTMozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36\v\200\0\0\207HTTP_ACCEPTtext/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,app"..., 1240) = 1240 <0.000060>
# 从fd读取1240字节数据, nginx通过cgi协议向cgi程序交流数据
09:10:52.751569 read(3, "\1\4\0\1\0\0\0\0", 8) = 8 <0.000029>
# 从fd读取8字节数据, 疑似cgi标记尾参数

09:10:52.751685 lstat("/home/speauty/PhpstormProjects/XDebug/index.php", {st_dev=makedev(0x8, 0x2), st_ino=11677842, st_mode=S_IFREG|0664, st_nlink=1, st_uid=1000, st_gid=1000, st_blksize=4096, st_blocks=8, st_size=39, st_atime=1621326231 /* 2021-05-18T16:23:51.886290838+0800 */, st_atime_nsec=886290838, st_mtime=1621326206 /* 2021-05-18T16:23:26.030695433+0800 */, st_mtime_nsec=30695433, st_ctime=1621326206 /* 2021-05-18T16:23:26.030695433+0800 */, st_ctime_nsec=30695433}) = 0 <0.000036>
09:10:52.751881 lstat("/home/speauty/PhpstormProjects/XDebug", {st_dev=makedev(0x8, 0x2), st_ino=11677764, st_mode=S_IFDIR|0775, st_nlink=3, st_uid=1000, st_gid=1000, st_blksize=4096, st_blocks=8, st_size=4096, st_atime=1621326208 /* 2021-05-18T16:23:28.278660231+0800 */, st_atime_nsec=278660231, st_mtime=1621326206 /* 2021-05-18T16:23:26.030695433+0800 */, st_mtime_nsec=30695433, st_ctime=1621326206 /* 2021-05-18T16:23:26.030695433+0800 */, st_ctime_nsec=30695433}) = 0 <0.000027>
09:10:52.752030 lstat("/home/speauty/PhpstormProjects", {st_dev=makedev(0x8, 0x2), st_ino=11535344, st_mode=S_IFDIR|0775, st_nlink=4, st_uid=1000, st_gid=1000, st_blksize=4096, st_blocks=8, st_size=4096, st_atime=1621305495 /* 2021-05-18T10:38:15.129185253+0800 */, st_atime_nsec=129185253, st_mtime=1621325497 /* 2021-05-18T16:11:37.726187251+0800 */, st_mtime_nsec=726187251, st_ctime=1621325497 /* 2021-05-18T16:11:37.726187251+0800 */, st_ctime_nsec=726187251}) = 0 <0.000026>09:10:52.752173 lstat("/home/speauty", {st_dev=makedev(0x8, 0x2), st_ino=11539164, st_mode=S_IFDIR|0755, st_nlink=55, st_uid=1000, st_gid=1000, st_blksize=4096, st_blocks=8, st_size=4096, st_atime=1621384607 /* 2021-05-19T08:36:47.192934664+0800 */, st_atime_nsec=192934664, st_mtime=1621385072 /* 2021-05-19T08:44:32.371170591+0800 */, st_mtime_nsec=371170591, st_ctime=1621385072 /* 2021-05-19T08:44:32.371170591+0800 */, st_ctime_nsec=371170591}) = 0 <0.000026>
09:10:52.752315 lstat("/home", {st_dev=makedev(0x8, 0x2), st_ino=11534337, st_mode=S_IFDIR|0755, st_nlink=3, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=8, st_size=4096, st_atime=1621298069 /* 2021-05-18T08:34:29.984991526+0800 */, st_atime_nsec=984991526, st_mtime=1606266613 /* 2020-11-25T09:10:13.970999772+0800 */, st_mtime_nsec=970999772, st_ctime=1606266613 /* 2020-11-25T09:10:13.970999772+0800 */, st_ctime_nsec=970999772}) = 0 <0.000026>
# 从目标文件到根目录直接子目录反向依次检测文件信息

09:10:52.752601 rt_sigaction(SIGPROF, NULL, {sa_handler=0x55ace118f290, sa_mask=~[ILL TRAP ABRT BUS FPE KILL SEGV CONT STOP TSTP TTIN TTOU SYS RTMIN RT_1], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f8602fe5210}, 8) = 0 <0.000032>
# SIGPROF表示使用setitimer指定的Profiling Interval Timer所产生
# SA_RESTORER 使被信号打断的系统调用自动重新发起, 据说已废弃
# SA_SIGINFO 使用 sa_sigaction 成员而不是 sa_handler 作为信号处理函数
09:10:52.752834 rt_sigaction(SIGHUP, NULL, {sa_handler=0x55ace118f290, sa_mask=~[ILL TRAP ABRT BUS FPE KILL SEGV CONT STOP TSTP TTIN TTOU SYS RTMIN RT_1], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f8602fe5210}, 8) = 0 <0.000025>
# SIGHUP 在用户结束终端连接时发出(关闭终端,断开ssh),系统对SIGHUP信号的默认处理是终止收到该信号的进程.所以若是程序中没有捕捉该信号,当收到该信号时,进程就会退出
09:10:52.752976 rt_sigaction(SIGINT, NULL, {sa_handler=0x55ace118f290, sa_mask=~[ILL TRAP ABRT BUS FPE KILL SEGV CONT STOP TSTP TTIN TTOU SYS RTMIN RT_1], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f8602fe5210}, 8) = 0 <0.000025>
09:10:52.753095 rt_sigaction(SIGQUIT, NULL, {sa_handler=0x55ace118f290, sa_mask=~[ILL TRAP ABRT BUS FPE KILL SEGV CONT STOP TSTP TTIN TTOU SYS RTMIN RT_1], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f8602fe5210}, 8) = 0 <0.000023>
09:10:52.753194 rt_sigaction(SIGTERM, NULL, {sa_handler=0x55ace118f290, sa_mask=~[ILL TRAP ABRT BUS FPE KILL SEGV CONT STOP TSTP TTIN TTOU SYS RTMIN RT_1], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f8602fe5210}, 8) = 0 <0.000023>
09:10:52.753292 rt_sigaction(SIGUSR1, NULL, {sa_handler=0x55ace118f290, sa_mask=~[ILL TRAP ABRT BUS FPE KILL SEGV CONT STOP TSTP TTIN TTOU SYS RTMIN RT_1], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f8602fe5210}, 8) = 0 <0.000023>
09:10:52.753655 rt_sigaction(SIGUSR2, NULL, {sa_handler=0x55ace118f290, sa_mask=~[ILL TRAP ABRT BUS FPE KILL SEGV CONT STOP TSTP TTIN TTOU SYS RTMIN RT_1], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f8602fe5210}, 8) = 0 <0.000039>

09:10:52.753800 setitimer(ITIMER_PROF, {it_interval={tv_sec=0, tv_usec=0}, it_value={tv_sec=3600, tv_usec=0}}, NULL) = 0 <0.000144>

09:10:52.754098 rt_sigaction(SIGPROF, {sa_handler=0x55ace118f290, sa_mask=~[ILL TRAP ABRT BUS FPE KILL SEGV CONT STOP TSTP TTIN TTOU SYS RTMIN RT_1], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f8602fe5210}, NULL, 8) = 0 <0.000028>
09:10:52.754253 rt_sigprocmask(SIG_UNBLOCK, [PROF], NULL, 8) = 0 <0.000025>

09:10:52.754445 openat(AT_FDCWD, "/home/speauty/PhpstormProjects/XDebug/index.php", O_RDONLY) = 4 <0.000054>
09:10:52.754600 fstat(4, {st_dev=makedev(0x8, 0x2), st_ino=11677842, st_mode=S_IFREG|0664, st_nlink=1, st_uid=1000, st_gid=1000, st_blksize=4096, st_blocks=8, st_size=39, st_atime=1621326231 /* 2021-05-18T16:23:51.886290838+0800 */, st_atime_nsec=886290838, st_mtime=1621326206 /* 2021-05-18T16:23:26.030695433+0800 */, st_mtime_nsec=30695433, st_ctime=1621326206 /* 2021-05-18T16:23:26.030695433+0800 */, st_ctime_nsec=30695433}) = 0 <0.000026>
09:10:52.754779 fstat(4, {st_dev=makedev(0x8, 0x2), st_ino=11677842, st_mode=S_IFREG|0664, st_nlink=1, st_uid=1000, st_gid=1000, st_blksize=4096, st_blocks=8, st_size=39, st_atime=1621326231 /* 2021-05-18T16:23:51.886290838+0800 */, st_atime_nsec=886290838, st_mtime=1621326206 /* 2021-05-18T16:23:26.030695433+0800 */, st_mtime_nsec=30695433, st_ctime=1621326206 /* 2021-05-18T16:23:26.030695433+0800 */, st_ctime_nsec=30695433}) = 0 <0.000025>
09:10:52.754937 fstat(4, {st_dev=makedev(0x8, 0x2), st_ino=11677842, st_mode=S_IFREG|0664, st_nlink=1, st_uid=1000, st_gid=1000, st_blksize=4096, st_blocks=8, st_size=39, st_atime=1621326231 /* 2021-05-18T16:23:51.886290838+0800 */, st_atime_nsec=886290838, st_mtime=1621326206 /* 2021-05-18T16:23:26.030695433+0800 */, st_mtime_nsec=30695433, st_ctime=1621326206 /* 2021-05-18T16:23:26.030695433+0800 */, st_ctime_nsec=30695433}) = 0 <0.000025>
09:10:52.755085 mmap(NULL, 39, PROT_READ, MAP_SHARED, 4, 0) = 0x7f8600000000 <0.000048>
09:10:52.755227 getcwd("/", 4095)       = 2 <0.000031>
09:10:52.755373 chdir("/home/speauty/PhpstormProjects/XDebug") = 0 <0.000026>
09:10:52.755535 munmap(0x7f8600000000, 39) = 0 <0.000038>
09:10:52.755642 close(4)                = 0 <0.000023>
09:10:52.755733 chdir("/")              = 0 <0.000022>
09:10:52.755823 times({tms_utime=0, tms_stime=0, tms_cutime=0, tms_cstime=0}) = 1718163428 <0.000020>
09:10:52.755911 write(2, "\0", 1)       = 1 <0.000021>
09:10:52.756032 setitimer(ITIMER_PROF, {it_interval={tv_sec=0, tv_usec=0}, it_value={tv_sec=0, tv_usec=0}}, NULL) = 0 <0.000020>
09:10:52.756153 write(3, "\1\6\0\1\0H\0\0X-Powered-By: PHP/7.3.25\r\nContent-type: text/html; charset=UTF-8\r\n\r\nx124\1\3\0\1\0\10\0\0\0\0\0\0\0\0\0\0", 96) = 96 <0.000126>
09:10:52.756369 shutdown(3, SHUT_WR)    = 0 <0.000048>
09:10:52.756517 recvfrom(3, "\1\5\0\1\0\0\0\0", 8, 0, NULL, NULL) = 8 <0.000162>
09:10:52.756869 recvfrom(3, "", 8, 0, NULL, NULL) = 0 <0.000073>
09:10:52.757039 close(3)                = 0 <0.000098>
09:10:52.757264 setitimer(ITIMER_PROF, {it_interval={tv_sec=0, tv_usec=0}, it_value={tv_sec=0, tv_usec=0}}, NULL) = 0 <0.000065>
09:10:52.757462 accept(8,


# 涉及函数原型
# int poll(struct pollfd fd[], nfds_t nfds, int timeout); 监视并等待多个文件描述符的属性变化
# ssize_t read(int fd, void *buf, size_t count[请求读取的字节数]); 从fd中读取buf, 并返回成功读取字节长度
# ssize_t write(int fd, const void *buf, size_t count); 成功返回写入的字节数, 出错返回-1
# int lstat(const char *path, struct stat *buf[返回文件的信息, 针对符号链接, 返回链接本身, 而不是而非目标文件]); 成功为0, 否则为-1
# clock_t times(struct tms *buf);
# int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); 检查并改变信号
# int openat(int dirfd, const char *pathname, int flags); 打开或创建一个文件

Debug 模式

xdebug.mode = debug

PHP => 客户端[ c ] ide[phpstorm] => 服务端[ s ]

大致流程: 连接 s => s 获取配置相关参数[例如 show_hidden 等] => sc 核对状态 => 进入断点 s 发送断点位置, c 响应, 并输出一些头参数和超全局变量 => 根据 s 发送的指令, 是否下一断点和退出( detach ).

就交互模型来说, 和常规 cs 无异, 只不过这里的相关指定从 s 发出, s 响应. 在配置上 xdebug.client_host 也还是有一定道理.

# 未打开 ide[phpstorm]
10:11:48.201559 connect(4, {sa_family=AF_INET, sin_port=htons(9003), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (操作现在正在进行) <0.000180>
10:11:48.201941 poll([{fd=4, events=POLLIN|POLLPRI|POLLOUT}], 1, 200) = 1 ([{fd=4, revents=POLLIN|POLLOUT|POLLERR|POLLHUP}]) <0.000079>
10:11:48.202186 close(4)                = 0 <0.000107>
10:11:48.202440 write(2, "NOTICE: PHP message: Xdebug: [Step Debug] Could not connect to debugging client. Tried: 127.0.0.1:9003 (through xdebug.client_host/xdebug.client_port) :-(\n", 155) = 155 <0.000043>
# 尝试连接 xdebug.client 失败, 为此, 还是要把ide打开, 至少有对应client
# 开启ide
# 浏览器访问 http://127.0.0.1/index.php?XDEBUG_SESSION_START=12456, 这个数字好像可以随便键入, 那边都可以进入断点过程
# 下面仅贴了部分终端输出, 基本上是非debug下没有的

# 连接debug客户端
10:26:28.812154 socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) = 4 <0.000057>
# ...
10:26:28.812465 connect(4, {sa_family=AF_INET, sin_port=htons(9003), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (操作现在正在进行) <0.000176>
# ...
10:26:28.813977 getpid()                = 6992 <0.000023>
10:26:28.814080 write(4, "510\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<init xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" fileuri=\"file:///home/speauty/PhpstormProjects/XDebug/index.php\" language=\"PHP\" xdebug:language_version=\"7.3.25\" protocol_version=\"1.0\" appid=\"6992\" idekey=\"1543\"><engine version=\"3.0.4\"><![CDATA[Xdebug]]></engine><author><![CDATA[Derick Rethans]]></author><url><![CDATA[https://xdebug.org]]></url><copyright><![CDATA[Copyright (c) 2002-2021 by Derick Rethans]]></copyright></init>\0", 515) = 515 <0.000115>
10:26:28.814395 getpid()                = 6992 <0.000072>

# 设置参数 show_hidden?
10:26:28.814628 recvfrom(4, "feature_set -i 1 -n show_hidden -v 1\0", 128, 0, NULL, NULL) = 37 <0.006103>
10:26:28.821038 write(4, "219\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<response xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" command=\"feature_set\" transaction_id=\"1\" feature=\"show_hidden\" success=\"1\"></response>\0", 224) = 224 <0.000183>
10:26:28.821476 recvfrom(4, "feature_set -i 2 -n max_depth -v 1\0", 128, 0, NULL, NULL) = 35 <0.001402>
10:26:28.823115 write(4, "217\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<response xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" command=\"feature_set\" transaction_id=\"2\" feature=\"max_depth\" success=\"1\"></response>\0", 222) = 222 <0.000178>
10:26:28.823516 recvfrom(4, "feature_set -i 3 -n max_children -v 100\0", 128, 0, NULL, NULL) = 40 <0.000989>
10:26:28.824714 write(4, "220\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<response xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" command=\"feature_set\" transaction_id=\"3\" feature=\"max_children\" success=\"1\"></response>\0", 225) = 225 <0.000106>
10:26:28.824979 recvfrom(4, "feature_set -i 4 -n extended_properties -v 1\0", 128, 0, NULL, NULL) = 45 <0.001083>
10:26:28.826304 write(4, "227\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<response xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" command=\"feature_set\" transaction_id=\"4\" feature=\"extended_properties\" success=\"1\"></response>\0", 232) = 232 <0.000085>
10:26:28.826553 recvfrom(4, "feature_set -i 5 -n notify_ok -v 1\0", 128, 0, NULL, NULL) = 35 <0.000947>
10:26:28.828013 write(4, "217\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<response xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" command=\"feature_set\" transaction_id=\"5\" feature=\"notify_ok\" success=\"1\"></response>\0", 222) = 222 <0.000083>
10:26:28.828268 recvfrom(4, "feature_set -i 6 -n resolved_breakpoints -v 1\0", 128, 0, NULL, NULL) = 46 <0.002878>
10:26:28.831476 write(4, "228\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<response xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" command=\"feature_set\" transaction_id=\"6\" feature=\"resolved_breakpoints\" success=\"1\"></response>\0", 233) = 233 <0.000163>

# 输出检测?
10:26:28.831891 recvfrom(4, "stdout -i 7 -c 1\0", 128, 0, NULL, NULL) = 17 <0.001965>
10:26:28.834330 write(4, "192\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<response xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" command=\"stdout\" transaction_id=\"7\" success=\"1\"></response>\0", 197) = 197 <0.000165>

# 双方核对状态
10:26:28.834733 recvfrom(4, "status -i 8\0", 128, 0, NULL, NULL) = 12 <0.001122>
10:26:28.836063 write(4, "210\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<response xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" command=\"status\" transaction_id=\"8\" status=\"starting\" reason=\"ok\"></response>\0", 215) = 215 <0.000154>
10:26:28.836632 recvfrom(4, "step_into -i 9\0", 128, 0, NULL, NULL) = 15 <0.001137>
10:26:28.838063 write(4, "320\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<response xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" command=\"step_into\" transaction_id=\"9\" status=\"break\" reason=\"ok\"><xdebug:message filename=\"file:///home/speauty/PhpstormProjects/XDebug/index.php\" lineno=\"2\"></xdebug:message></response>\0", 325) = 325 <0.000153>
10:26:28.838377 recvfrom(4, "eval -i 10 -- aXNzZXQoJF9TRVJWRVJbJ1BIUF9JREVfQ09ORklHJ10p\0", 128, 0, NULL, NULL) = 59 <0.001622>
# isset($_SERVER['PHP_IDE_CONFIG'])
10:26:28.840307 write(4, "225\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<response xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" command=\"eval\" transaction_id=\"10\"><property type=\"bool\"><![CDATA[0]]></property></response>\0", 230) = 230 <0.000149>
10:26:28.840594 recvfrom(4, "eval -i 11 -- aXNzZXQoJF9TRVJWRVJbJ1NFUlZFUl9OQU1FJ10p\0", 128, 0, NULL, NULL) = 55 <0.001293>
# isset($_SERVER['SERVER_NAME'])
10:26:28.842200 write(4, "225\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<response xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" command=\"eval\" transaction_id=\"11\"><property type=\"bool\"><![CDATA[1]]></property></response>\0", 230) = 230 <0.000179>
10:26:28.842590 recvfrom(4, "eval -i 12 -- KHN0cmluZykoJF9TRVJWRVJbJ1NFUlZFUl9OQU1FJ10p\0", 128, 0, NULL, NULL) = 59 <0.001478>
# (string)($_SERVER['SERVER_NAME'])
10:26:28.844345 write(4, "278\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<response xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" command=\"eval\" transaction_id=\"12\"><property type=\"string\" size=\"16\" encoding=\"base64\"><![CDATA[d3d3LnhkZWJ1Zy5sb2NhbA==]]></property></response>\0", 283) = 283 <0.000232>
# www.xdebug.local 域名
10:26:28.844695 recvfrom(4, "eval -i 13 -- KHN0cmluZykoJF9TRVJWRVJbJ1NFUlZFUl9QT1JUJ10p\0", 128, 0, NULL, NULL) = 59 <0.001722>
10:26:28.846724 write(4, "257\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<response xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" command=\"eval\" transaction_id=\"13\"><property type=\"string\" size=\"2\" encoding=\"base64\"><![CDATA[ODU=]]></property></response>\0", 262) = 262 <0.000122>
# 85 端口
10:26:28.847028 recvfrom(4, "eval -i 14 -- KHN0cmluZykoJF9TRVJWRVJbJ1JFUVVFU1RfVVJJJ10p\0", 128, 0, NULL, NULL) = 59 <0.000949>
10:26:28.848599 write(4, "302\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<response xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" command=\"eval\" transaction_id=\"14\"><property type=\"string\" size=\"36\" encoding=\"base64\"><![CDATA[L2luZGV4LnBocD9YREVCVUdfU0VTU0lPTl9TVEFSVD0xNTQz]]></property></response>\0", 307) = 307 <0.000136>
# /index.php?XDEBUG_SESSION_START=1543
10:26:28.848951 recvfrom(4, "breakpoint_set -i 15 -t line -f file:///home/speauty/PhpstormProjects/XDebug/index.php -n 2\0stack_get -i 16\0", 128, 0, NULL, NULL) = 108 <0.036324>
# 设置断点
10:26:28.885499 getpid()                = 6992 <0.000009>
10:26:28.885591 write(4, "359\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<notify xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" name=\"breakpoint_resolved\"><breakpoint type=\"line\" resolved=\"resolved\" filename=\"file:///home/speauty/PhpstormProjects/XDebug/index.php\" lineno=\"2\" state=\"enabled\" hit_count=\"0\" hit_value=\"0\" id=\"69920014\"></breakpoint></notify>\0", 364) = 364 <0.000065>
10:26:28.885786 write(4, "223\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<response xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" command=\"breakpoint_set\" transaction_id=\"15\" id=\"69920014\" resolved=\"resolved\"></response>\0", 228) = 228 <0.000053>
10:26:28.885887 write(4, "313\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<response xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" command=\"stack_get\" transaction_id=\"16\"><stack where=\"{main}\" level=\"0\" type=\"file\" filename=\"file:///home/speauty/PhpstormProjects/XDebug/index.php\" lineno=\"2\"></stack></response>\0", 318) = 318 <0.000064>
10:26:28.886041 recvfrom(4, "stack_get -i 17\0", 128, 0, NULL, NULL) = 16 <0.001209>
10:26:28.887338 write(4, "313\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<response xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" command=\"stack_get\" transaction_id=\"17\"><stack where=\"{main}\" level=\"0\" type=\"file\" filename=\"file:///home/speauty/PhpstormProjects/XDebug/index.php\" lineno=\"2\"></stack></response>\0", 318) = 318 <0.000064>
10:26:28.887429 recvfrom(4, "context_names -i 18\0", 128, 0, NULL, NULL) = 20 <0.152711>
10:26:29.040304 write(4, "330\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<response xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" command=\"context_names\" transaction_id=\"18\"><context name=\"Locals\" id=\"0\"></context><context name=\"Superglobals\" id=\"1\"></context><context name=\"User defined constants\" id=\"2\"></context></response>\0", 335) = 335 <0.000928>
10:26:29.041387 recvfrom(4, "context_get -i 19 -d 0 -c 0\0", 128, 0, NULL, NULL) = 28 <0.000169>
10:26:29.041753 write(4, "198\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<response xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" command=\"context_get\" transaction_id=\"19\" context=\"0\"></response>\0", 203) = 203 <0.000141>
10:26:29.042071 recvfrom(4, "context_get -i 20 -d 0 -c 1\0", 128, 0, NULL, NULL) = 28 <0.000995>
10:26:29.043387 write(4, "8546\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<response xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" command=\"context_get\" transaction_id=\"20\" context=\"1\"><property name=\"$_COOKIE\" fullname=\"$_COOKIE\" type=\"array\" children=\"1\" numchildren=\"1\" page=\"0\" pagesize=\"100\"><property name=\"XDEBUG_SESSION\" fullname=\"$_COOKIE[&quot;XDEBUG_SESSION&quot;]\" type=\"string\" size=\"4\" encoding=\"base64\"><![CDATA[MTU0Mw==]]></property></property><property name=\"$_ENV\" fullname=\"$_ENV\" type=\"array\" children=\"0\" numchildren=\"0\" page=\"0\" pagesize=\"100\"></property><property name=\"$_FILES\" fullname=\"$_FILES\" type=\"array\" children=\"0\" numchildren=\"0\" page=\"0\" pagesize=\"100\"></property><property name=\"$_GET\" fullname=\"$_GET\" type=\"array\" children=\"1\" numchildren=\"1\" page=\"0\" pagesize=\"100\"><property name=\"XDEBUG_SESSION_START\" fullname=\"$_GET[&quot;XDEBUG_SESSION_START&quot;]\" type=\"string\" size=\"4\" encoding=\"base64\"><![CDATA[MTU0Mw==]]></property></property><property name=\"$_POST\" fullname=\"$_POST\""..., 8552) = 8552 <0.000112>
# 获取超全局变量[Superglobals]
# 1543

10:26:29.043616 recvfrom(4, "context_get -i 21 -d 0 -c 2\0", 128, 0, NULL, NULL) = 28 <0.009563>
10:26:29.053321 write(4, "198\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<response xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" command=\"context_get\" transaction_id=\"21\" context=\"2\"></response>\0", 203) = 203 <0.000132>
10:26:29.053586 recvfrom(4,

# 下一个
10:26:29.043616 recvfrom(4, "context_get -i 21 -d 0 -c 2\0", 128, 0, NULL, NULL) = 28 <0.009563>
10:26:29.053321 write(4, "198\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<response xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" command=\"context_get\" transaction_id=\"21\" context=\"2\"></response>\0", 203) = 203 <0.000132>
10:26:29.053586 recvfrom(4, "run -i 22\0", 128, 0, NULL, NULL) = 10 <546.710713>
10:35:35.764602 chdir("/")              = 0 <0.000046>
10:35:35.764835 times({tms_utime=3, tms_stime=3, tms_cutime=0, tms_cstime=0}) = 1718671729 <0.000075>
10:35:35.765148 write(2, "\0", 1)       = 1 <0.000044>
10:35:35.765519 write(4, "216\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<stream xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" type=\"stdout\" encoding=\"base64\"><![CDATA[WC1Qb3dlcmVkLUJ5OiBQSFAvNy4zLjI1]]></stream>\0", 221) = 221 <0.000175>
# X-Powered-By: PHP/7.3.25

10:35:35.765973 write(4, "188\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<stream xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" type=\"stdout\" encoding=\"base64\"><![CDATA[DQo=]]></stream>\0", 193) = 193 <0.000399>
# ' '
10:35:35.766655 write(4, "332\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<stream xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" type=\"stdout\" encoding=\"base64\"><![CDATA[U2V0LUNvb2tpZTogWERFQlVHX1NFU1NJT049MTU0MzsgZXhwaXJlcz1XZWQsIDE5LU1heS0yMDIxIDAzOjI2OjI4IEdNVDsgTWF4LUFnZT0zNjAwOyBwYXRoPS87IFNhbWVTaXRlPVN0cmljdA==]]></stream>\0", 337) = 337 <0.000342>
# Set-Cookie: XDEBUG_SESSION=1543; expires=Wed, 19-May-2021 03:26:28 GMT; Max-Age=3600; path=/; SameSite=Strict

10:35:35.767521 write(4, "188\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<stream xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" type=\"stdout\" encoding=\"base64\"><![CDATA[DQo=]]></stream>\0", 193) = 193 <0.000118>
# ' '
10:35:35.768016 write(4, "236\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<stream xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" type=\"stdout\" encoding=\"base64\"><![CDATA[Q29udGVudC10eXBlOiB0ZXh0L2h0bWw7IGNoYXJzZXQ9VVRGLTg=]]></stream>\0", 241) = 241 <0.000105>
# Content-type: text/html; charset=UTF-8

10:35:35.768354 write(4, "188\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<stream xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" type=\"stdout\" encoding=\"base64\"><![CDATA[DQo=]]></stream>\0", 193) = 193 <0.000077>
# ' '
10:35:35.768600 write(4, "188\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<stream xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" type=\"stdout\" encoding=\"base64\"><![CDATA[DQo=]]></stream>\0", 193) = 193 <0.000115>
# ' '
10:35:35.768931 write(4, "188\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<stream xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" type=\"stdout\" encoding=\"base64\"><![CDATA[eDIz]]></stream>\0", 193) = 193 <0.000229>
# 标准输出
# x23

10:35:35.769437 write(4, "208\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<response xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" command=\"run\" transaction_id=\"22\" status=\"stopping\" reason=\"ok\"></response>\0", 213) = 213 <0.000102>
10:35:35.769678 recvfrom(4, "detach -i 23\0", 128, 0, NULL, NULL) = 13 <0.006505>
# 离开
10:35:35.776446 write(4, "211\0<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n<response xmlns=\"urn:debugger_protocol_v1\" xmlns:xdebug=\"https://xdebug.org/dbgp/xdebug\" command=\"detach\" transaction_id=\"23\" status=\"stopping\" reason=\"ok\"></response>\0", 216) = 216 <0.000185>
10:35:35.776900 close(4)                = 0 <0.000108>
10:35:35.777224 close(4)                = -1 EBADF (错误的文件描述符) <0.000114>
# 连续关闭, 导致对应fd不存在
最后总结

PHP 而言, 所谓 Debug, 就是定位当前行为及其上下文, 采用 cs 模型, 不过指令由 s 端发出, 是个被动操作. 这里借助 strace 指令分析进程函数调用, 如果再进一步切入 PHP 解释器就更好了. 需要注意的是, 做这种调试, 需要将 PHP 的工作进程( work proccess )设置为1, 确保跟踪进程为当前执行进程.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值