10
votes

I am using Visual Studio Code with the PHP Debug extension to debug a Laravel project. But some breakpoints are ignored and I cannot figure out why. I insist on the fact that not all breakpoints are ignored. For instance all breakpoints at method declarations are ignored but those at variable declarations are hit.

The Xdebug part of my php.ini:

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

This is my 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
        }
    ]
}

What I tried:

  • Changing the default port 9000 to 9001
  • Uninstalling and reinstalling the PHP debug extension (you never know)

Example: the "•" indicates a line breakpoint. All the breakpoints in the code sample below are ignored.

 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'
     ]);
 }

How to get Xdebug with Visual Studio Code hitting all breakpoints or is this normal behaviour? Thank you in advance for your help.

Update #1 (08/07/2019)

The Zend extension path is specified in my php.ini like below.

zend_extension = "/usr/local/Cellar/[email protected]/7.2.18/pecl/20170718/xdebug.so"

And I tried to add php.validate.executablePath in my settings.json.

Update #2 (08/08/2019)

According to the comments and the answers at the time of this update, Xdebug ignoring some lines is the normal behavior. My questions then are why are some lines ignored? What kinds of lines are ignored? Is there an official list?

4
Where those non-working breakpoints are? What kind of lines they are? A screenshot is welcome. Try placing xdebug_break(); in your code and see if it will trigger it. P.S. I suggest placing breakpoints on actual lines of code and they better be single liners / simple instructions. Due to the way how PHP generated byte code, some breakpoints have different line that you would expect (e.g. multi line array declaration -- it would be somewhere in the middle). P.P.S. Maybe VSC does not support "method breakpoints" (when it's placed on the function declaration line). - LazyOne
P.S. If one breakpoint works and another does not, then changing ports will do nothing. Changing port may be needed only if you do not receive any connection from Xdebug at all (e.g. some another service is running on that port, e.g. php-fpm is a typical case). In any case: enable & collect and then check Xdebug log -- it will tell where it tries to connect (and if it's successfull or not), on what lines breakpoints are set etc. - LazyOne
Please add the code and also on which particular lines the breakpoints don't work? - Tarun Lalwani
P.P.S. Xdebug 2.8 should have "breakpoint validation" mechanism in place: it will give instant feedback if breakpoint set in that line will be hit or not. Obviously, debug client (IDE/editor) would need to be aware of that/support this as well. - LazyOne
@rkeet Please use whatever URLs you need (the more the better): it will make a better answer without a need for going through the comments, e.g. explanation with why such breakpoints are not getting hit/links to tickets where such explanation is present etc. - LazyOne

4 Answers

4
votes

Running it in PhpStorm, but as Xdebug runs on PHP, the behavior is the same.

Xdebug stops when stuff is "done", on the lines that things are "done". This can be function calls, variable assignments, data transformations, etc. All these have in common that they must be explicit. Implicit assignments are ignored.

Xdebug does not pause execution for breakpoints placed "in" an action. Which is why the first breakpoint in your code will not work, and the second will.

Explicit & implicit example:

$attributes = [                   // this is implicitly an array, no pausing execution
    'business_name' => 'DANONE'   // this is explicitly assigned a string, execution paused
];

With some screenshots (code is from Symfony 4 public/index.php, with some obvious additions - blue background is paused execution "current line"):

example 1

Clearly executing functions inside an if() statement - it pauses

example 2

As we can see, breakpoints on all 3 lines of this array. However, the only one it pauses on is the assignment of the key/value pair. This is explicitly done, the array itself is implicitly declared.

example 3

Here we explicitly declare $testArray to be an array. So: it pauses.

example 4

This is to be complete, could've added it above. Implicit setting of type array, but explicit assigning of key/value.


So: yes.

If you had placed your breakpoints slightly different, they would've paused the execution. Not pausing on the implicit ones is normal behavior.


To be complete:

On local Apache installation I've got the following config:

[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;

But I normally run this in Docker. In the docker-compose PHP image:

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
  • (to enable xdebug, set XDEBUG_ENABLED environment config to 1 in application when starting using docker-compose up)
  • (replace "ProjectName" with the name of the project, use that name in your "servers" config in PhpStorm settings for Xdebug)

and in the Dockerfile

pecl install xdebug-2.7.2 redis && \
docker-php-ext-enable xdebug redis && \
  • (make sure to replace xdebug-2.7.2 with a version you want / is compatible with your PHP version, check that here)

Edit: additional based on comments on OP's question.

There's plenty of bug reports (see those comments, credit to LazyOne for finding them).

The last URL he provided is interesting as it's about the upcoming V2.8.0 (currently in 2.8.0beta1, not general release), about which he comments in this ticket about Xdebug not pausing execution on the implicit assignments:

I've just merged this into the master branch, which will become part of 2.8.0. I will release 2.7.2 soon (this week, today?!), and then probably next week a 2.8alpha1 release so that people can try this out.

(quote from 2019-05-06 12:49 by Derick, writer of Xdebug)

You can have a look at the changelog page or the roadmap for Xdebug.

The roadmap shows all of the features / fixes which will be included.

For 2.8.0 it shows that support for IDE's will be added for IDE's to show whether or not a breakpoint can be resolved. It's current release date is set for 2019-09-30.

Released

3
votes

It's not available to break by defined array in vscode
my suggestion is to get some if or other code, like this:

 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'
     ]);
 }

and continue with press f10 button

1
votes

I too faced this problem, with laravel, im posting what steps I did to fix this problem I'm using laragon for PHP

added a new php version, also updated composers PHP path(don't know if this step is requiered, but I did it and pointed to latest PHP version)

downloaded xdebg.dll and placed in the folder

updated configuration in 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

i dont have xdebug.remote_port = 9000

in 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
        }
    ]
}

on vscode

In Preferences --> Settings (ctrl+,)

Add/update: php.validate.executablePath: "D:\lrgn\bin\php\php-7.2.7\php.exe" (mine was here)

Restarted server(laragon) stoped laravel did a composer update on project(not sure is this stage require) started laravel project again

on browser open laravel project

on vscode set some brakepoints even in methods

in debug section -> Listen for XDebug

on browser reloaded the page

yes, it's a direct hit

-3
votes

I faced the same error.

I fixed that just download old version of xdebug.

You can download it from this link.