xdebug / vscode-php-debug

PHP Debug Adapter for Visual Studio Code 🐞⛔
MIT License
763 stars 178 forks source link

New vscode August update broke xDebug listener on port 9003 (Laravel Sail) #922

Closed ktalich closed 6 months ago

ktalich commented 10 months ago

PHP version: 8.2 (Laravel Sail image) Xdebug version: v3.2.1 VS Code extension version: v1.33.0

Your launch.json: { "version": "0.2.0", "configurations": [ { "name": "Listen for Sail Xdebug", "type": "php", "request": "launch", "port": 9003, "pathMappings": { "/var/www/html": "${workspaceFolder}" }, "hostname": "localhost", "ignore": ["**/vendor/**/*.php"], "xdebugSettings": { "max_data": 65536, "show_hidden": 1, "max_children": 100, "max_depth": 3 } }, ] } Xdebug php.ini config: zend_extension=xdebug.so

Steps to Reproduce:

  1. Update to the latest vscode version
  2. Create a new Laravel Sail project (https://laravel.com/docs/10.x/installation#laravel-and-docker): curl -s https://laravel.build/example-app | bash cd example-app edit .env and set SAIL_XDEBUG_MODE=develop,debug,coverage
  3. Add vscode launch configuration: create new ".vscode" folder in the project root, create file "launch.json" in the new folder, place contents: { "version": "0.2.0", "configurations": [ { "name": "Listen for Sail Xdebug", "type": "php", "request": "launch", "port": 9003, "log": true, "pathMappings": { "/var/www/html": "${workspaceFolder}" }, "hostname": "localhost", "ignore": ["**/vendor/**/*.php"], "xdebugSettings": { "max_data": 65536, "show_hidden": 1, "max_children": 100, "max_depth": 3 } }, ] }
  4. Start Laravel Sail: ./vendor/bin/sail up -d
  5. Set a break-point somewhere and try to execute or use artisan tinker
  6. Laravel will output that it can't connect to xDebug client: Could not connect to debugging client. Tried: host.docker.internal:9003 (through xdebug.client_host/xdebug.client_port).

I'll just add that it doesn't work for me, mainly on a project in progress, and it worked until yesterday... Then vscode updated itself and it no longer works. If I downgrade the version to July (vscode 1.81) it works again.

zobo commented 10 months ago

Hi! Thanks or the report, I'll try to reproduce it here.

zobo commented 10 months ago

I followed your instructions and found the problem. You define "hostname": "localhost" witch instructs PHP Debug to listen only for local connections. Since PHP lives inside Docker that is not localhost. Remove the hostname directive and it should work.

Also, these two are not needed: "max_children": 100, "max_depth": 3 as they are set automatically.

technatelogy commented 10 months ago

Still doesn't work for me after removing the hostname argument (which previously worked).

technatelogy commented 10 months ago

Looks like it's because it's listening on the ipv6 interface by default now after removing the hostname argument. I was able to workaround by setting hostname to "0.0.0.0".

zobo commented 10 months ago

Interesting. Linux? And you have a public v6 address? Usually sockets by default listen on both address families.

zobo commented 10 months ago

Can you also try "hostname":"::". That should bind to dual stack.

zobo commented 10 months ago

And please see what sysctl net.ipv6.bindv6only says it is set to.

technatelogy commented 10 months ago

For me it's a Windows/Ubuntu WSL2 environment with a php docker container. I also had previously set hostname to localhost and it worked fine, though now I'm not sure why since like you said it's connecting from a different container not localhost.

If I set it to "::" (which it shows is the default unset value) it still only seems to listen on ipv6. My netstat shows: image and I am unable to connect from inside the docker container.

Where with it set to 0.0.0.0 it listens on ipv4: image and it works.

My sysctl net.ipv6.bindv6only is set to 0 inside my WSL2 ubuntu instance.

zobo commented 10 months ago

Interesting, thanks. It's also interesting that this started to happen with VS Code upgrade - as mentioned in the linked task - that updated the Node runtime. I'll do some tests, as it looks like there is somethin somewhere that sets v6only flag when creating the socket...

technatelogy commented 10 months ago

Yeah, that's kind of what I was guessing as well. Not a big deal since I can workaround but still thanks for taking a look!

zobo commented 10 months ago

I'm considering installing WSL2 on my PC, but am afraid it will mess up my VirtualBox... Can you give me your uname -a output, then I'll write in the vscode linked task. Can't reproduce the issue in one of my VMs for now Linux docker 4.19.0-20-amd64 #1 SMP Debian 4.19.235-1 (2022-03-17) x86_64 GNU/Linux

carlos-additio commented 10 months ago

Looks like it's because it's listening on the ipv6 interface by default now after removing the hostname argument. I was able to workaround by setting hostname to "0.0.0.0".

To me this solution finally made it work again

zobo commented 10 months ago

@carlos-additio can you describe your environment? Did it also start happening on VS Code update? Are you also on WSL2? Can you give me the output of your uname -a and cat /proc/sys/net/ipv6/bindv6only? Thanks!

carlos-additio commented 10 months ago

@carlos-additio can you describe your environment? Did it also start happening on VS Code update? Are you also on WSL2? Can you give me the output of your uname -a and cat /proc/sys/net/ipv6/bindv6only? Thanks!

uname -a Linux DESKTOP-LJ2HH80 5.10.16.3-microsoft-standard-WSL2 #1 SMP Fri Apr 2 22:23:49 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

cat /proc/sys/net/ipv6/bindv6only 0

zobo commented 10 months ago

Thanks a lot. Intriguing how both cases don't have the bind ipv6 only option set, but Node behaves as it was...

I guess I'll need to install WSL2 to test this. Thanks a lot.

technatelogy commented 10 months ago

Here's my uname -a ouput: Linux leviathan 5.15.90.1-microsoft-standard-WSL2 #1 SMP Fri Jan 27 02:56:13 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

oortasertecfarma commented 9 months ago

The same issue is happening to me on a Mac with Laravel Sail (docker). It has been solved by changing "localhost" to "0.0.0.0."

zobo commented 9 months ago

The same issue is happening to me on a Mac with Laravel Sail (docker). It has been solved by changing "localhost" to "0.0.0.0."

That makes sense, if you are running VS Code on the host and not inside the container. This means the two processes are on different networks. How come you had host: localhost set in the first place? It would be good to find out where people are getting this wrong information from and try to get it fixed. Thanks!

oortasertecfarma commented 9 months ago

I guess I copied the configuration I had on a Windows machine with WSL and VSCode running inside the container. The interesting thing is that it has been working for a long time until now.

carlos-additio commented 9 months ago

The same issue is happening to me on a Mac with Laravel Sail (docker). It has been solved by changing "localhost" to "0.0.0.0."

That makes sense, if you are running VS Code on the host and not inside the container. This means the two processes are on different networks. How come you had host: localhost set in the first place? It would be good to find out where people are getting this wrong information from and try to get it fixed. Thanks!

Maybe some other people arrived to some configurations to debug the project like in here: https://stackoverflow.com/questions/62104199/issues-when-debugging-php-in-vscode-using-docker-and-wsl2

ryan-l-robinson commented 8 months ago

I'm guessing ours is the same issue since it also started with the August update and is similarly fixed by rolling back. We were at the time using an Oracle Linux based image and now have switched to the official Drupal image (drupal:php8.1-apache), both with the same problem. Context: Windows 10 with WSL 2.

The problem behaviour is a freezing as soon as it tries to execute any PHP command, with no warnings or errors.

Based on another blog I found that seemed to be talking about the same thing, I added pathMappings. Before that I didn't use pathMappings at all. I was not using hostname at all, either, but am now going to try with hostname of 0.0.0.0. My launch.json is now:

{
  // 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": "Xdebug",
      "type": "php",
      "request": "launch",
      "port": 9003,
      "log": true,
      "pathMappings": {
        "/opt/drupal": "${workspaceFolder}"
      },
      "hostname": "0.0.0.0"
    }
  ]
}

The first few tests seem to be working, but I said the same thing about adding pathMapping last week. It sometimes seems to work for a bit and then for some reason doesn't again after that.

Update: a couple hours later, I am back to it freezing once it hits any PHP command.

This is my docker-php-ext-xdebug.ini file:

zend_extension=xdebug
xdebug.mode=coverage,debug,develop,profile
xdebug.discover_client_host = 1
xdebug.client_port = 9003
xdebug.max_nesting_level = 512
xdebug.start_with_request = yes
xdebug.client_host = host.docker.internal
xdebug.log = /var/log/xdebug.log
xdebug.idekey = VSCODE
MichaelPietroforte commented 7 months ago

"hostname": "0.0.0.0" changed DEBUG CONSOLE output from Listening on { address: '::', family: 'IPv6', port: 9003 } to Listening on { address: '0.0.0.0', family: 'IPv4', port: 9003 }. However, on MacOS VS Code is not listening at all on 9003: lsof -i -P -n | grep '9003' -> no result On Windows, I don't have this issue.

zobo commented 7 months ago

I have a M1 Mac mini, Sonoma 14.0. Running VSC 1.85.0 and php-debug 1.34.0 . Bost ipv6 and ipv4 connections work, I could not find any problem. I even tried your lsof and I do se open and connected ports.

It's very strange that the plugin would report it is listening and than that port would not be open...

What's the version of your setup?

MichaelPietroforte commented 7 months ago

Thanks for the fast reply! It's an M2 Macbook with Ventura. Can you post your entire launch.json?

zobo commented 7 months ago

It's actually just the default launch.json that gets generated. I also did not configure Xdebug in any way, just let pecl and homebrew install it. (aside from a path problem). I used "Launch currently open script" and the quick run / debug top right of the editor. Both worked.

{
    // 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": 9003
        },
        {
            "name": "Launch currently open script",
            "hostname": "0.0.0.0",
            "type": "php",
            "request": "launch",
            "program": "${file}",
            "cwd": "${fileDirname}",
            "port": 0,
            "log": true,
            "runtimeArgs": [
                "-dxdebug.start_with_request=yes"
            ],
            "env": {
                "XDEBUG_MODE": "debug,develop",
                "XDEBUG_CONFIG": "client_port=${port}"
            }
        },
        {
            "name": "Launch Built-in web server",
            "type": "php",
            "request": "launch",
            "runtimeArgs": [
                "-dxdebug.mode=debug",
                "-dxdebug.start_with_request=yes",
                "-S",
                "localhost:0"
            ],
            "program": "",
            "cwd": "${workspaceRoot}",
            "port": 9003,
            "serverReadyAction": {
                "pattern": "Development Server \\(http://localhost:([0-9]+)\\) started",
                "uriFormat": "http://localhost:%s",
                "action": "openExternally"
            }
        }
    ]
}
MichaelPietroforte commented 7 months ago

Thanks! Turns out it works with a local folder. However, when I connect via SSH to a remote server, VS Code is not listening on port 6003. I wonder why?

zobo commented 7 months ago

What kind of SSH extension are you using? VSCode Remote SSH? Can you be specific with the extension ID so I can try it here.

I do some Flutter development and I had huge macOS permission problems when I tried to use VSC Remote SSH. There was a change in macOS that does not grant proper permission... or something..

MichaelPietroforte commented 7 months ago

I am using Remote - SSH from Microsoft: ms-vscode-remote.remote-ssh. I also installed Remote Explorer ms-vscode.remote-explorer and Remote - SSH: Editing Configuration Files ms-vscode-remote.remote-ssh-edit

zobo commented 7 months ago

Tried it now, and it still works. (The port is random).

image

Very strange. Try to inspect ports on the embedded terminal inside VSCode. Try different ports.

MichaelPietroforte commented 7 months ago

I don't see VS Code listening in in your screenshot. It is not a port issue because port 9003 is not occupied. Is your VS Code folder on the remote system? Does the remote .vscode folder contain your launch.json?

zobo commented 7 months ago

VSC has a multi process architecture. So the process listening for the debugger is actually "node".

In this setup I was running the editor frontend on my PC and the vscode remote on my Mac. The files and php process are located on the Mac. In the case before everything was running on the Mac, I was using sitting at the Mac.

zobo commented 7 months ago

Yes. The .vscode folder and launch.json are also on the Mac. When you use vscode remote ssh you don't see your local files.

zobo commented 7 months ago

For reference: https://code.visualstudio.com/docs/remote/ssh

MichaelPietroforte commented 7 months ago

I think you have a different setup. VS Code runs on my Mac. The remote system is Ubuntu. I connect via SSH in VS Code to a folder on the Ubuntu system. Thus, launch.json has to be stored on the remote system because my VS Code folder is there. Everything works normally in VS Code. VS Code Explorer has access to the remote folder, I can edit remote files, search through all remote files, launch.json is automatically stored by Xdebug on the remote system, etc. I also get no error message when I start Xdebug. The output in DEBUG CONSOLE is the same as with a local folder. It is just that VS Code is not listening on the Mac.

The funny thing is that if I mount the remote folder on my Mac via MacFUSE, it works. It is just that MacFUSE is very slow.

zobo commented 7 months ago

I now understand. If you look at the provided link https://code.visualstudio.com/docs/remote/ssh it explains how "vsc remote" works. Your vscode and all the extensions are actually running on your Ubuntu server. Running on your Mac is only a frontend of the editor. So when you start the listen for Xdebug the process that listens on port 9003 in on your Ubuntu server.

MichaelPietroforte commented 7 months ago

Oh yeah, that makes perfect sense. So, I guess there is no way to use Xdebug with the Remote SSH extension.

Anyway, thanks a lot for the help!

zobo commented 7 months ago

There is absolutely a way to use it. You just need to change your xdebug.ini so that Xdebug connects to your server/localhost. You can try to set xdebug.client_host=localhost or if that doesn't work give some details about your server setup (php and xdebug version, web server, docker?).

MichaelPietroforte commented 7 months ago

I don't know if I really understand. Maybe I shouldn't do this after 13 hours of work. It is php8.1-fpm with Apache. I added xdebug.client_host=localhost to php.ini, but it is not working. I don't see something listening on 9003 on the remote system. Xdebug in VS Code starts but nothing happens when I load a web page.

MichaelPietroforte commented 7 months ago

Correction. It works now! I connected to the wrong server. Thank you so much! Your help is very much appreciated!

zobo commented 6 months ago

Awesome. I'll close this issue and there was no other feedback.

tyhopp commented 6 months ago

I got stuck on this today, and @technatelogy's workaround of setting hostname to 0.0.0.0 finally got my breakpoints get hit. I'm also using a WSL2 and Docker setup.

Rummaging around the codebase it looks like this codepath is hit where hostname is passed to server.listen as undefined.

An uneducated guess is it would then reach this codepath in Node because a port is defined but not a host, and then Node tries to figure out what hostname to assign somewhere here.

One thing I tried was setting a default value of localhost or 0.0.0.0 if no args.hostname is defined like this:

const listenPort = args.port === undefined ? 9003 : args.port;
const listenHostname = args.hostname === undefined ? 'localhost' : args.hostname;
server.listen(listenPort, listenHostname);

This fixed the issue, but I don't know if this would have other side effects or if it actually solves whatever the underlying issue is. I'm not all too familiar with XDebug - is localhost the real default hostname or de facto? Node looks like it defines the default IPv4 address as 0.0.0.0.

I'd be happy to contribute this change if it seems like something worth pursuing @zobo. Otherwise this will hopefully add to the context for others who land here.

zobo commented 5 months ago

Hi @tyhopp . Sorry for the late reply and thanks for the analysis.

First, changing the hostname default to localhost would not be a good idea, because any a bit more than trivial-local-only setup needs to communicate with processes that are on other networks (remote, docker...).

The Node docs for server.listen state that when host is absent (undefined) it will try to listen on IPv6 :: and then on IPv4 0.0.0.0.

Also note that vscode updated its Node from 16 to 18 back in August 2023 and that probably caused the start of these issues. I did look at the docs, but could not find something useful here. https://nodejs.org/dist/latest-v16.x/docs/api/all.html#all_net_serverlistenport-host-backlog-callback -> https://nodejs.org/dist/latest-v18.x/docs/api/all.html#all_net_serverlistenport-host-backlog-callback

Potentially 0.0.0.0 could be a good default for hostname, but I'd much rather just leave the decision to Node as is now. If there is somebody out there that uses IPv6 for communication between Xdebug and php-debug this would be a breaking change for them...

However, I did just recently upgraded my PC and am now able to run WSL2 - and already discovering all sorts of problems with it - so I will revisit this issue.

zobo commented 5 months ago

Hey @tyhopp. Can you drop me your xdebug.ini settings, I'd like to try and reproduce this and so far nothing I tried shows any problems.

tyhopp commented 5 months ago

Thanks for revisiting this @zobo, here's a reproduction of my setup https://github.com/tyhopp/php-xdebug-docker