Xdebug与Visual Studio Code无法识别某些断点

11

我正在使用带有PHP Debug扩展的Visual Studio Code来调试Laravel项目。但是某些断点被忽略了,我无法弄清为什么。我坚持认为并非所有断点都被忽略。例如,所有方法声明处的断点都被忽略,但在变量声明处的断点会被触发。

我的php.ini文件中与Xdebug相关的部分:

xdebug.profiler_enable = 1
xdebug.remote_autostart = 1
xdebug.remote_connect_back=1
xdebug.remote_enable = 1
xdebug.remote_port = 9000

这是我的launch.json文件:

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Listen for XDebug",
            "type": "php",
            "request": "launch",
            "port": 9001,
            "log": true
        },
        {
            "name": "Launch currently open script",
            "type": "php",
            "request": "launch",
            "program": "${file}",
            "cwd": "${fileDirname}",
            "port": 9000
        }
    ]
}

我尝试过:

  • 将默认端口9000更改为9001
  • 卸载并重新安装PHP调试扩展(你永远不知道)

示例:在代码示例中,“•”表示行断点。所有断点都被忽略。

 public function testCreateWhenAllParametersAreCorrectlySpecifiedReturnsCompany()
 {
•    $attributes = [
         'business_name' => 'DANONE'
     ];

     $address = factory(Address::class)->create();

     $company = Company::create($attributes, $address);

     $this->assertInstanceOf(Company::class, $company);

     $this->assertDatabaseHas('companies', [
•        'address_id' => $address->id,
         'business_name' => 'DANONE'
     ]);
 }
如何在Visual Studio Code中启用Xdebug,以便能够命中所有断点或者这是正常行为?感谢您的帮助。
更新 #1(08/07/2019):
我的php.ini中指定了Zend扩展路径,如下所示。
zend_extension = "/usr/local/Cellar/php@7.2/7.2.18/pecl/20170718/xdebug.so"

我试图在我的settings.json文件中添加php.validate.executablePath

更新#2(2019年8月8日)

根据此更新时的评论和答案,Xdebug忽略某些行是正常行为。那么我的问题是:为什么会忽略某些行?哪些行被忽略了?是否有官方清单?


2
那些不起作用的断点在哪里?它们是什么样的行?欢迎提供截图。试着在你的代码中放置 xdebug_break(); 并查看是否会触发它。附言:建议在实际的代码行上设置断点,最好是单行/简单指令。由于 PHP 生成的字节码方式不同,某些断点的行与您预期的不同(例如,多行数组声明-它将位于中间某个位置)。附言2:也许 VSC 不支持“方法断点”(当它放置在函数声明行上时)。 - LazyOne
1
如果一个断点起作用而另一个断点不起作用,则更改端口将无济于事。仅当您根本没有从Xdebug收到任何连接时(例如,某些其他服务正在该端口上运行,例如php-fpm是典型情况),才可能需要更改端口。在任何情况下:启用并收集,然后检查Xdebug日志--它将告诉您它尝试连接的位置(以及是否成功),设置了哪些行断点等。 - LazyOne
2
请添加代码,并指出断点不起作用的特定行? - Tarun Lalwani
1
P.P.S. Xdebug 2.8 应该有“断点验证”机制:如果在该行设置断点,则会立即给出反馈,指示是否会触发断点。显然,调试客户端(IDE/编辑器)也需要知道并支持此功能。 - LazyOne
1
@rkeet 请使用你需要的任何网址(越多越好):这将使答案更好,而无需查看评论,例如,说明为什么这些断点未被触发/链接到已有此类说明的票证等。 - LazyOne
显示剩余12条评论
4个回答

4
在PhpStorm中运行它,但由于Xdebug运行在PHP上,所以其行为是相同的。 Xdebug会在完成某些事情时停止,在完成这些事情的行上。这可以是函数调用、变量赋值、数据转换等等。所有这些都有一个共同点,就是它们必须是明确的。隐式赋值将被忽略。
Xdebug不会为放置在“操作内部”的断点暂停执行。这就是为什么你代码中的第一个断点不起作用,而第二个断点会起作用的原因。
显式和隐式示例:
$attributes = [                   // this is implicitly an array, no pausing execution
    'business_name' => 'DANONE'   // this is explicitly assigned a string, execution paused
];

以下是一些屏幕截图(代码取自Symfony 4的public/index.php,加入了一些显而易见的内容- 蓝色背景表示暂停执行的“当前行”):

example 1

很明显,在一个if()语句中执行函数-它会暂停。

example 2

我们可以看到,这个数组的所有3行都有断点。然而,唯一暂停的是键/值对的赋值。这是明确指定的,而数组本身是隐式声明的。

example 3

在这里,我们明确声明$testArray为数组。因此:它会暂停。

example 4

这是为了完整性而添加的,本来可以将其添加到上面。隐式设置类型为数组,但明确分配键/值。


所以:是的。

如果您稍微调整了断点位置,它们就会暂停执行。不在隐式声明的情况下暂停是正常行为。


完整配置如下:

我在本地Apache安装中拥有以下配置:

[XDEBUG]
zend_extension = C:\xampp\php\ext\php_xdebug-2.7.1-7.3-vc15-x86_64.dll

xdebug.remote_mode = req
xdebug.remote_connect_back = 1
xdebug.default_enable = 1
xdebug.remote_autostart = 1
xdebug.remote_enable = 1
xdebug.remote_port = 9000
xdebug.remote_handler = dbgp
xdebug.max_nesting_level = 200;

但我通常在Docker中运行此操作。 在docker-compose PHP镜像中:

environment:
  PHP_XDEBUG_ENABLED: ${XDEBUG_ENABLED:-0}
  PHP_IDE_CONFIG: ${PHP_IDE_CONFIG:-serverName=ProjectName}
  XDEBUG_CONFIG: >
    idekey=PHPSTORM 
    remote_host=${XDEBUG_REMOTE_HOST_IP:-host.docker.internal}
    remote_port=${XDEBUG_REMOTE_PORT:-9000}
    remote_enable=1
  • (要启用xdebug,请在使用docker-compose up启动应用程序时,在环境配置中将XDEBUG_ENABLED设置为1)
  • (将"ProjectName"替换为项目的名称,然后在PhpStorm设置的Xdebug的"servers"配置中使用该名称)

并且在Dockerfile

pecl install xdebug-2.7.2 redis && \
docker-php-ext-enable xdebug redis && \
  • (请确保将xdebug-2.7.2替换为您想要的版本/与您的PHP版本兼容的版本,在这里检查)

编辑:基于评论对OP问题的补充。

有很多错误报告(请参见这些评论,感谢LazyOne找到它们)。

他提供的最后一个URL非常有趣,因为它涉及即将推出的V2.8.0(目前是2.8.0beta1,不是一般发布版),关于此,他在此票证中评论了Xdebug在隐式赋值上没有暂停执行:

我刚刚将其合并到主分支中,这将成为2.8.0的一部分。我很快就会发布2.7.2(本周,今天?!),然后可能在下周发布2.8alpha1版本,以便人们可以尝试一下。

(来自Xdebug作者Derick于2019年5月6日12:49的引用)

您可以查看更改日志页面路线图以获取Xdebug的信息。

路线图显示将包括所有功能/修复的内容。

对于2.8.0,它显示将添加对IDE的支持,以便IDE显示是否可以解析断点。其当前发布日期设置为2019-09-30。

已发布。


3

在VSCode中无法按定义的数组进行断点调试。 我的建议是获取某些if或其他代码,例如:

 public function testCreateWhenAllParametersAreCorrectlySpecifiedReturnsCompany()
 {
•   $debug = 'true';
    $attributes = [
         'business_name' => 'DANONE'
     ];

     $address = factory(Address::class)->create();

     $company = Company::create($attributes, $address);

•    $this->assertInstanceOf(Company::class, $company);

     $this->assertDatabaseHas('companies', [
         'address_id' => $address->id,
         'business_name' => 'DANONE'
     ]);
 }

然后按下f10按钮继续进行。


1
我也可以添加一些日志记录。Xdebug与IDE相结合的目的不是为了避免调试代码吗? - louisfischer
你看到那个回复了吗?https://dev59.com/mVMI5IYBdhLWcg3wA2js#tTInoYgBc1ULPQZF0OoM - Moshe Fortgang

1
我也遇到了这个问题,使用的是 Laravel。以下是我解决此问题所采取的步骤:
我使用 Laragon 作为 PHP 的开发环境,在其中添加了一个新的 PHP 版本,并更新了 composer 的 PHP 路径(不确定是否必需,但我还是这样做了,并指向了最新的 PHP 版本)。
我下载了 xdebug.dll 并将其放置在文件夹中。
我更新了 php.ini 中的配置。
[xdebug]    
 zend_extension = D:\lrgn\bin\php\php-7.2.7\ext\php_xdebug-2.6.1-7.2-vc15-nts-x86_64.dll
 xdebug.remote_autostart=1
 xdebug.remote_enable=1
 xdebug.remote_connect_back = 1
 ;xdebug.remote_log= D:\lrgn\bin\log\xdebug.log

我没有xdebug.remote_port = 9000。
在launch.json中。
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Listen for XDebug",
            "type": "php",
            "request": "launch",
            "port": 9000
        },
        {
            "name": "Launch currently open script",
            "type": "php",
            "request": "launch",
            "program": "${file}",
            "cwd": "${fileDirname}",
            "port": 9000
        }
    ]
}

在 vscode 上

进入 Preferences --> Settings (ctrl+,)

添加/更新: php.validate.executablePath: "D:\lrgn\bin\php\php-7.2.7\php.exe" (我的路径在这里)

重启服务器(laragon) 停止 laravel 在项目上运行 composer update(不确定是否需要) 重新启动 laravel 项目

在浏览器中打开 laravel 项目

在 vscode 中设置一些断点,甚至在方法中

在调试部分 -> 启用 XDebug 监听

在浏览器中重新加载页面

是的,它直接命中了


laragon <3 的 "<3" 是代表心形还是小于3呢? - Black
谢谢您的回答。您是说使用Laragon解决了您的问题吗?Zend扩展路径在我的php.ini中指定,我尝试在settings.json中添加php.validate.executablePath,但断点仍然被忽略。 - louisfischer

-2

我遇到了同样的错误。

我解决了这个问题,只需下载旧版本的xdebug即可。

您可以从此link下载它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接