使用 Xdebug 进行远程调试导致 PHP 脚本执行停止

Remote debugging with Xdebug causes PHP script execution to halt

我正在尝试使用 xdebug 调试远程 PHP 脚本。当为网站启用 xdebug 时,如果 xdebug 能够建立 tcp 连接,PHP 脚本会冻结,就像等待执行断点一样。网页的 JavaScript 部分显示正确,只是等待 PHP 代码到完成页面所需的 return 数据。

这在过去有效。我这辈子都想不通为什么。

如果 xdebug 无法与远程主机建立 TCP 会话,一切正常。

我使用 Angular 10 作为我的开发环境,PhpStorm 作为我的 IDE.

环境:

Debian bullseye (testing)
Apache2.4
PHP 7.4.11
mpm_prefork
xdebug.so 2.9.8

我也试过xdebug.so v2.8.x and v3.0.0 (Beta)没效果。

当前 /etc/php/7.4/mods-available/xdebug.ini:

#set xdebug flags/values
zend_extension=xdebug.so    

xdebug.remote_autostart=0
xdebug.remote_enable=1
xdebug.remote_connect_back=0
xdebug.remote_host=MyClientIP    
xdebug.remote_port=9099
xdebug.idekey=PHPSTORM
    
#xdebug logger
xdebug.remote_log = /var/log/xdebug/xdebug.log

虽然我使用 PhpStorm 开发我的应用程序,但这个问题与我的 IDE 无关。为了说明这一点,我从 xdebug.org 下载了 dbgbClient.exe

使用脚本时,会在客户端和服务器之间创建一个会话。

客户端输出:

dbgpClient.exe  -p 9099 -f
Xdebug Simple DBGp client (0.4.1)
Copyright 2019-2020 by Derick Rethans

Waiting for debug server to connect on port 9099.
Connect from 10.130.189.1:39144
DBGp/1.0: Xdebug 2.9.8 — For PHP 7.4.11
Debugging file:///home/init/DEV/MT4/php-services/ClassAPI.php (ID: 70831/PHPSTORM)
1 | feature_get
1 | supports_async: supported > 0

xdebug.log 来自服务器:

[70831] Log opened at 2020-10-14 20:59:24
[70831] I: Connecting to configured address/port: myClientIP:9099.
[70830] Log opened at 2020-10-14 20:59:24
[70830] I: Connecting to configured address/port: MyClientIP:9099.
[70831] I: Connected to client. :-)
[70831] -> <init xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" fileuri="file:///home/init/DEV/MT4/php-services/ClassAPI.php" language="PHP" xdebug:language_version="7.4.11" protocol_version="1.0" appid="70831" idekey="PHPSTORM"><engine version="2.9.8"><![CDATA[Xdebug]]></engine><author><![CDATA[Derick Rethans]]></author><url><![CDATA[https://xdebug.org]]></url><copyright><![CDATA[Copyright (c) 2002-2020 by Derick Rethans]]></copyright></init>

[70830] I: Connected to client. :-)
[70830] -> <init xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" fileuri="file:///home/init/DEV/MT4/php-services/ClassAPI.php" language="PHP" xdebug:language_version="7.4.11" protocol_version="1.0" appid="70830" idekey="PHPSTORM"><engine version="2.9.8"><![CDATA[Xdebug]]></engine><author><![CDATA[Derick Rethans]]></author><url><![CDATA[https://xdebug.org]]></url><copyright><![CDATA[Copyright (c) 2002-2020 by Derick Rethans]]></copyright></init>

至此网页开始创建。

如果我发出一个 run 命令和一个额外的回车符 return 或两个,调试会话继续并且屏幕结束。

客户端示例:

(cmd) run
2 | run > stopping/ok

(cmd)
Error while handling connection: Error reading length: EOF
Disconnect
Connect from 10.130.189.1:39146
DBGp/1.0: Xdebug 2.9.8 — For PHP 7.4.11
Debugging file:///home/init/DEV/MT4/php-services/ClassAPI.php (ID: 70830/PHPSTORM)
1 | feature_get
1 | supports_async: supported > 0

(cmd) run
2 | run > stopping/ok

(cmd)
Error while handling connection: Error reading length: EOF
Disconnect

上述的 xdebug 日志:

[70831] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="feature_get" transaction_id="1" feature_name="supports_async" supported="1"><![CDATA[0]]></response>

[70831] <- run -i 2
[70831] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="run" transaction_id="2" status="stopping" reason="ok"></response>

[70831] <- run -i 3
[70831] Log closed at 2020-10-14 21:00:32

[70830] <- feature_get -i 1 -n supports_async
[70830] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="feature_get" transaction_id="1" feature_name="supports_async" supported="1"><![CDATA[0]]></response>

[70830] <- run -i 2
[70830] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="run" transaction_id="2" status="stopping" reason="ok"></response>

[70830] <- run -i 3
[70830] Log closed at 2020-10-14 21:00:41

[70829] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="feature_set" transaction_id="4" status="stopping" reason="ok"></response>

[70829] Log closed at 2020-10-14 21:13:17

[70832] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="feature_set" transaction_id="4" status="stopping" reason="ok"></response>

[70832] Log closed at 2020-10-14 21:13:38

感谢您阅读到这里。我确定有人有解决方案。

这是相关部分:

Error while handling connection: Error reading length: EOF Disconnect

首先,

xdebug 并不意味着连接到远程(实时)站点。

即使 stunnel 正常工作,它仍可能由于某种原因无法重新连接...例如

xdebug.remote_host=EXTERNAL_ROUTER_IP
xdebug.remote_connect_back=1

并且port-forward:9099到路由器内部MyClientIP

嗯,事实证明我的开发 PC 通过 VPN 连接到我公司的网络之间存在一些问题。我都同时工作。多亏了 IT 拧紧了安全螺丝 (firewall rules)。

虽然我的 PhpStorm 会看到 PHPSTORM cookie 并在正确的端口上建立 TCP 会话,但协议不会继续完成。我猜网络上有某种类型的智能防火墙。

秘诀是在我的 PC 和 linux 服务器之间建立一个 ssh 隧道,如下所示:

ssh -R 9000:localhost:9000 username_goes_here@hostname_goes_here

我也修改了我的/etc/php/7.4/mods-available/xdebug.ini:(神奇酱是xdebug.remote_host=127.0.0.1

zend_extension=xdebug.so    
xdebug.remote_log=/var/log/xdebug/xdebug.log    
xdebug.remote_host=127.0.0.1
xdebug.remote_enable=1
xdebug.idekey=PHPSTORM

因此ssh隧道将连接到服务器上的9000端口,PC上的本地端口9000作为隧道的另一端。

接下来要做的就是设置 PhpStorm。为此(以及这些说明的来源)请参阅 here.

请注意 - 我只测试了通过网络浏览器访问 php 脚本。我没有测试过基于 CLI 的 PHP 脚本,但我猜答案大同小异。

如果您需要有关 ssh 端口转发(隧道)的更多信息,请参阅 here