【问题标题】:Remote debugging with Xdebug causes PHP script execution to halt使用 Xdebug 进行远程调试会导致 PHP 脚本执行停止
【发布时间】:2021-01-29 08:39:33
【问题描述】:

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

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

如果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 命令和额外的一两个回车,调试会话将继续,屏幕结束。

客户端示例:

(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

感谢您阅读本文。我敢肯定有人有解决方案。

【问题讨论】:

  • 请注意——我尝试过使用 SSH 隧道,mpm-event(根本无法让它工作)。尝试访问简单脚本
  • 首先,我建议录制小截屏视频,展示这一切(最好使用 IDE)——它可能会揭示一些缺失的位/细微差别。这可以是一些测试代码(如果您不想显示,则不会显示真实的项目名称等)。
  • 除此之外:1) 我在第一个 Xdebug 日志片段中看到 2 个同时调试会话(在第二个日志片段中看到 4 个)。可能是你的 Angular 进行 API 调用……这就是为什么在一个简单的 PHP 页面上用最少的代码测试它(例如 &lt;?php $a = 1; $b = 3; $c = $a + $b; echo "$c\n"; - 它自己的行上的每个语句)应该更容易理解。 PhpStorm 可以同时运行几个会话。
  • 2) 如果 Xdebug 连接到调试客户端/IDE .. 并且它遇到断点,那么是的——它将在那里等待响应。这就是run 命令有帮助的原因——它告诉“继续退出脚本”。我建议在 PhpStorm 中打开 Breakpoints 窗口并将它们全部删除。在 PhpStorm 中,它也可能因为“Break on first line...”或类似(另一个)选项而停止——如果该条目脚本没有可用的路径映射,通常会发生...检查 PhpStorm 设置中的 Xdebug 部分。
  • 感谢您的建议。我尝试了相同的结果。 xdebug 的行为就像它应该在 PHP 代码的第一行停止,即使不存在这样的配置。我尝试了本地和远程调试会话,但没有成功。一旦建立会话,脚本就会停止,就像在断点处等待一样。

标签: php tcp xdebug remote-debugging


【解决方案1】:

这是相关部分:

处理连接时出错:读取长度错误:EOF 断开连接

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

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

xdebug.remote_host=EXTERNAL_ROUTER_IP
xdebug.remote_connect_back=1

并将端口转发:9099 到路由器中的内部MyClientIP

【讨论】:

  • php脚本的远程调试一直到上个月才工作。虽然您对公司防火墙的评论很有价值,但我能够使用 telnet ClientIP 9099 从服务器连接到客户端。此外,我电脑上的命令行客户端显示连接以及 xdebug 日志。我相信 EOF 表明客户端关闭了连接。 Apache2、xdebug 和 php4.7.11 之间存在一些问题,导致出现竞争或锁定问题。顺便说一句,php 日志中没有任何内容。
  • xdebug 有自己的日志,这与 apache 关系不大。我不是指任何公司防火墙,但显然网络服务器上的防火墙...netstat 也应该显示正在发生的事情。它不能只使用一个连接;例如。当它在断点处中断然后无法恢复执行时。
  • 反向流量可能根本没有被路由......更新了我的答案。
  • 我在同一个子网上尝试了两台 Linux (Debian) 服务器。使用简单脚本 . 运行 Apache、PHP7.4、php-xdebug 2.9.6
  • 同样的问题。似乎 xDebug 正在等待一个不存在的断点。当客户端发出运行命令(两次)时,客户端会报告页面绘制和 EOF。 xdebug 日志显示“日志已关闭”我也厌倦了降级到 PHP 7.3 和相关应用程序。同样的问题。呃
【解决方案2】:

好吧,事实证明,我的开发 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

【讨论】:

  • 仅供参考 - 要调试远程 PHP CLI 脚本,请在“解释器选项”字段中添加 -dxdebug.remote_host=127.0.0.1
猜你喜欢
  • 2011-06-19
  • 2021-11-01
  • 2012-04-06
  • 2015-07-04
  • 1970-01-01
  • 2013-07-13
  • 2011-11-06
  • 1970-01-01
  • 2011-06-27
相关资源
最近更新 更多