Damjan Cvetko

Damjan Cvetko

Developer, System Architect, Hacker.

4 minutes read

I couldn’t make an update in a while, but I did manage to release a few things. February GitHub issue and March GitHub issue and April GitHub issue outline the work done.

The current version is 1.26.1.

Error on irrelevant env configuration

The extension will now throw an error saying Cannot set env without running a program. Please remove env from [xxx] configuration if the configuration contains env and neither program nor runtimeArgs.

I have noticed a number of issues on Stack Overflow and GitHub where people expect that they can set environment variables in env when within a listen configuration and then cannot understand why Xdebug isn’t working.

A typical scenario is where a user would have a default Xdebug ini configuration and then prepare this launch.json configuration:

  "configurations": [
      "name": "Listen for Xdebug",
      "type": "php",
      "request": "launch",
      "port": 9003,
      "env": {
        "XDEBUG_MODE": "debug,develop"

They reload the browser and don’t understand why the Xdeubg mode setting wasn’t altered.

What we need to understand here is that the extension does not spawn any processes and so in turn cannot influence the environment variables of an existing process.

So the extension will now throw an error. If there will be too many complaints, I will change it into a warning log.

Start debugging with stop on entry

Although there is no exposed native way to do this, a lot of debuggers offer starting debugging with immediately breaking on the first line of code. The functionality has always been there with the stopOnEntry launch option, what was added was a key binding to enable this feature directly. Now, when starting debug with F10 or F11 it’s the same as with F5 but with stopOnEntry enabled.

Eval cache

Another feature implemented, was the handling of eval responses. Until now, when something was eval-ed in the Debug Console only a limited depth of its children was returned, as defined by max_children.

Now, the same as other IDEs, VS Code will send an eval in the form of $GLOBALS['eval_cache']['${uuid}']=${args.expression} and then retrieve the global property $eval_cache['${uuid}']. This allows for incremental traversal of the eval response.

A while back I suggested that Xdebug itself could store the eval response in a temporary variable and keep it until the next step operation. This approach does not require engine changes, but could potentially pollute the global namespace…

Unix sockets

Xdebug allows connecting to a Unix socket instead of a TCP port. The PHP Debug extension could not listen on a Unix socket until now.

I got a request for this a while back, but couldn’t decide how to implement it until I actually did it. A user found a workaround by ignoring the port type and simply inputting /path/to/socket instead of 9003. My initial implementation was to add a new field to allow for Unix sockets, but when I compared the implementation to how Xdebug does it, I changed it and decided to use the hostname instead.

The hostname launch setting now accepts three formats:

  • unix:// to listen on a Unix socket like unix:///tmp/sock
  • \\ to listen on a windows pipe like \\?\pipe\sock or \\.\pipe\sock
  • IP hostname like or localhost when binding to a TCP port

Xdebug does not currently support Windows Pipes.

Small fixes

I also fixed a problem with traversing properties in extended format, extended logging a bit, fixed external console script on Mac and added the ExitedEvent after a long back-and-forth discussion with neovim / nvim-dap users and developers.


The last made me appreciate again that this extension is not only in use by VS Code. This is the reason why I make changes to it with such extra care.

I’m currently focusing on Xdebug Cloud support.

As always, ping me on Twitter or GitHub issues if you have problems or questions.

Also if you use the extension and it makes your life easier consider donating via GitHub Sponsors.

Recent posts

See more