ddev / ddev

Docker-based local PHP+Node.js web development environments
https://ddev.com
Apache License 2.0
2.74k stars 597 forks source link

More sophisticated xdebug step-debugging support (trigger?) #3731

Open nico-loeber opened 2 years ago

nico-loeber commented 2 years ago

Is there an existing issue for this?

Is your feature request related to a problem? Please describe

Me and a colleague evaluate the use of DDEV in our company (I use quite some time now for private purpose). In our everyday work we use xdebug a lot to debug issues. Often we need to debug a single Request. Also profiling is quite common to find bottlenecks in our code.

Currently DDEV just offers the options on and off, where on is debugging EVERY request and EVERY command on CLI. The need to switch xDebug on and off via a command and the lack of possibility to debug a single request make it impossible to use DDEV for our everyday work in its current configuration.

Also profiling and tracing is not possible without manually editing the PHP configuration.

Another a bit annoying thing is, that you get spammed with Xdebug: [Step Debug] Time-out connecting to debugging client, waited: 200 ms. Tried: host.docker.internal:9003 (through xdebug.client_host/xdebug.client_port) :-( as soon as xdebug is enabled and you run any php cli command.

Describe the solution you'd like

The common configuration for xDebug is to start on a trigger. This allows you to start debugging, profiling and tracing from your browser, or via your IDE when you start a cli debugging session.

Also it is possible to only debug the navigation event of the browsers which is especially usefull if you are working with an application where sub requests like files are only served by your application, as you get spammed with 50 debugging sessions or more.

The configuration used by my company for the use of xdebug looks like the following:

Xdebug 3 (PHP >= 7.2)

[xdebug]
xdebug.mode=develop,debug,profile,trace
xdebug.start_with_request=trigger

Xdebug 2 (PHP < 7.2)

[xdebug]
xdebug.remote_enable = ON
xdebug.remote_autostart = OFF
xdebug.remote_connect_back = ON
xdebug.coverage_enable = ON
xdebug.default_enable = ON
xdebug.remote_enable = ON
xdebug.profiler_enable = OFF
xdebug.profiler_enable_trigger = ON
xdebug.trace_enable_trigger = ON

I would like to use these configurations as a new default. Also the xdebug extension should be enabled by default, so you can profit from its development features like. Endless recursion detection, overloaded var_dump and other development features.

Of course this would be somehow a breaking change as people who are used to the behavior, that every request is debugged after enabling xdebug would now need to trigger the debugging session as shown below.

The ddev xdebug disable would be less important but might still be useful in case you would like to do performance comparisons as xDebug will affect your performance even without an active debugging session. This impact shouldn't be crucial for a development environment.

If this solution is accepted, I would like to create a pull request.

Describe alternatives you've considered

An alternative to changing the current behavior of ddev would be adding a new "xdebug mode" like ddev xdebug trigger or something like this. This would allow to introduce the new behavior in parallel of the current one. But this would add up much complexity for the user as well as for implementing the pull request.

Additional context

Starting a debugging / profiling session from browser: image

Starting a CLI debugging session from IDE: image

Documentation on how to debug with PHPStorm: https://www.jetbrains.com/help/phpstorm/configuring-xdebug.html#integrationWithProduct

Edit: I did update the configuration samples to remove one unrelated option as well as correcting the php version relation.

rfay commented 2 years ago

Thanks for this!

I do hope you've seen ddev xhprof and ddev blackfire, which IMO are way better techniques for profiling than xdebug has ever provided.

rfay commented 2 years ago

Note that xdebug 2 is long in the rearview mirror and irrelevant. If we do anything, it will involve xdebug 3 only.

Also, xdebug 3 is the only option in DDEV for PHP >= 7.2.

And @derickr very explicitly added the "Xdebug: [Step Debug] Time-out connecting to debugging client" in xdebug 3 because he wanted people to understand why things weren't working. There isn't a way to turn that off to my knowledge. We twitter-chatted about at at some point.

nico-loeber commented 2 years ago

I would just like to add some notes after a very productive talk with @rfay about this topic. I did show how you can perfectly start debug session from within your IDE or your browser with the settings noted above, without the need to do any configuration changes to ddev or running any command like ddev xdebug enable.

We came to the result that

However we do have some differing views on

I could try to create a pull request but I might need some support as I am not used to GoLang and don't know much about the internals of DDEV.

rfay commented 2 years ago

You don't actually need any golang experience to do this, it's all shell-scripting. Either in

And you can pioneer it all by just fiddling with a copy of the xdebug command locally.

rfay commented 2 years ago

I changed the scope of this to exclude profiling, which I think is a different topic, and an issue is welcome, but since ddev has the superior ddev xhprof and ddev blackfire it may not be reasonable to add xdebug profiling... but regardless it's not hard to do.

rfay commented 2 years ago

One additional thing we discussed that is relevant to any user is not to forget that you can change the PHP config for any project (including xdebug) with custom php config (docs). So anybody can already change to trigger, and have the config checked in for their project.

rfay commented 2 years ago

I note that just adding a .ddev/php/myconf.ini with the contents

[php]
xdebug.start_with_request=trigger

seems to get most of the behavior you're asking at least for step-debugging, is that correct? You still have to have PhpStorm listening when you want it listening, and you do have to ddev xdebug one time, but then you turn on and off usage of breakpoints using the Chrome extension... Note that you could easily put these into a post-start hook as well, or into a custom Dockerfile.

hooks:
  post-start:
    - exec-host: ddev xdebug on

I'm just trying to understand exactly what you're after. I did install the browser extension, which I haven't used for a few years because zero-config is so easy, and it works fine and is a fine way to control the flow of things.

nico-loeber commented 2 years ago

Yes, thanks for adding this quick fix in the issue as well!

I already tried the .ddev/php/xdebug.ini way with my colleague and it works well and as expected! :) And yes, of course you have to enable the xdebug extension for the configuration to take effect.

Please note, that you can also use the develop features of xDebug, which are quite useful, that way. https://xdebug.org/docs/develop

Also you do not need to start listening in phpstorm if you start a debugging session from within your IDE (Unit Test Debugging for example).

I will try to create a pull request this weekend, as I see a lot of advantages in this configuration and no drawbacks.

rfay commented 2 years ago

Related request:

rfay commented 1 year ago

I would sure love to pursue this this winter.

rfay commented 1 year ago

I wouldn't blame you for not wanting to take this on again after the amount of effort you put into it last year, but there are two good paths:

  1. Simple update to docs explaining this technique
  2. A new command in ddev to give this behavior.