xdebug makes PHP hang

I’ve found it’s a common misconception that you can’t have XDebug running all the time without impacting PHP performance.

There’s a few reasons you could be experiencing hangs or delays:

  • You have xdebug.remote_autostart set to 1.

    This will make XDebug try to contact your debug client on every PHP process. Web, console, whatever. Generally a bad idea! You could easily run into multiple requests trying to connect and stalling.

    It’s best to set this to 0, then use a browser extension to toggle your debugging session on or off, like:

    https://addons.mozilla.org/en-US/firefox/addon/easy-xdebug/

    The only time setting this to 1 is a good idea is when there is no other way to send the XDebug session start command (for example, when debugging an application that receives HTTP calls from a 3rd party machine).

    If you are doing console PHP, you can set an environment variable to toggle.
    On – export XDEBUG_CONFIG="idekey=netbeans-xdebug"

    Note it is important to set xdebug.remote_connect_back to 0, and remote_host to a valid host, because in console, XDebug won’t automatically know the location of your debugger from xdebug.remote_connect_back.

    While this is set, PHP run in CLI mode (like drush) will trigger debugging.

  • You had a debugging session open, and opened another one to the same debug client.

    For example, debugging index.php in your browser, opening a new tab, and debugging it again. The 2nd request will stall because your local debugger is busy.

    Suggestions: use the XDebug toggler to enable/disable debugging. You can start debugging in one browser tab, but turn it off for another.

  • Your application makes a URL call to itself, and you had xdebug.remote_autostart set to 1.

    (A combination of the above)

    The best example of this is using Drupal simpletests – you start a PHP process that connects to your debugger, but then the remote HTTP call inside of PHP also tries to connect. Your simpletests will stall indefinitely. Setting xdebug.remote_autostart to 0 ensures that the internal HTTP calls do not trigger XDebug.

    Caveat: Unfortunately, to actually debug a call inside of another call is somewhat complicated. You will have to turn off debugging in your browser/console, then manually inject

    ?XDEBUG_SESSION_START=mykey

    into your internal HTTP calls, disable xdebug.remote_connect_back, and set an xdebug.remote_host.

XDebug becomes incredibly flexible with xdebug.remote_connect_back and xdebug.remote_autostart – especially for debugging live servers where you do not want XDebug to take up any overhead. I’ll make another post on that soon – including bits about debug security and the debug proxy for handling multi-user debugging.

If you’re not set up with xdebug yet check out my quick start Linux + PHP + XDebug howto

  • Thanks you for your hint about remote_autostart.
    Now I can debug simpletest test cases, previously I can not, because netbeans and browser stop working before it reach the break point.

  • Great post, saved me a few headaches

  • Borislav

    Thanks, this was very helpful to me!

    I also use remote_autostart=1 in order to debug a webhook. In such a setup, when I try to start another php process, sure enough it hangs because XDebug wants to connect to my IDE. But if the IDE ignores the connection coming from XDebug, then the php process can continue. However, I don’t like to press the Ignore button each time a php process is started, so I set my phpStorm to ignore connections received through unregistered server configurations.

  • Ethan Mallove

    +1