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