Become a Patron!

My Amazon wishlist can be found here.

Life Line

The Xdebug Experience

Xdebug development is currently in its 17th year. I started working on it when PHP 4.2.0 had just been released. The first CVS commit added the (in)famous "maximum nesting level" functionality, to prevent PHP from crashing when your script would infinitely recurse. I had forgotten this, but apparently Xdebug has some origins in VL-SRM, a naive attempt to create an application server running PHP bananas (think of: Java beans). The VL prefix still lives on as part of my PHP internals debugging extension VLD.

Where Are We Now?

As with any legacy project, Xdebug has technical debt. Some of it I managed to address during the years by dropping support for older PHP versions. There is a fair amount of sub-optimal code, algorithmic, and design issues, which impact ease of configuration, usability, and performance.

Configuration Confusion

On the configuration side, take for example the 65 configuration settings. There are a few pointless ones (xdebug.extended_info, xdebug.remote_handler), a few that duplicate functionality (xdebug.trace_output_dir and xdebug.profiler_output_dir), and a few that should never be used together (xdebug.remote_enable and xdebug.profiler_enable).

Unproductive Usability

If we look at usability, there are situations where breakpoints don't break. Some of these I can likely address, whereas others I can not due to the way how PHP works internally (See also: The Mystery of the Missing Breakpoints). Having OPcache in the mix does not help either as it can create another set of problems where visible code has been optimised out.

To solve a third group of issues with breakpoints, the DBGp "breakpoint resolved" notification needs to be implemented in both Xdebug and IDEs.

Another issue is that both Xdebug and PHP-FPM use port 9000 as their default, although Xdebug's use of port 9000 precedes PHP-FPM's by about five years (2004 vs 2009).

And lastly, (potential) users often cite that it is "hard" to set Xdebug up. Although after talking to some of these users, it often becomes clear that the problem is not so much on the Xdebug side of things, but rather other tools: their IDE, Docker, SELinux, firewalls, etc. Improving this is a matter of education (and better error messages).

Poor Performance

On the performance side, there are some places with major issues, and some others with minor issues. Code coverage isn't particularly fast, and that needs an in-depth investigation. I have several ideas on where improvements in code coverage performance can be made—nonetheless, I would continue to put correctness over speed.

Even with Xdebug just loaded and enabled, there is too much of a performance impact. This is because Xdebug usually has every feature ready to go, even though you don't necessarily want to use all of these different features. For example, it is ludicrous to use single step debugging with the profiler turned on.

Although it's often possible to reduce the impact of feature sets by setting configuration options correctly, a better way to put Xdebug in a specific mode would be welcome.

What Needs to Be Done?

In order to address many of these problems, Xdebug must undergo a massive refactoring. As part of that effort, the refactoring must primarily focus on solving the above mentioned three categories, although improvements in code layout are also desirable.

As part of the refactoring process, the following primary tasks need to be completed, in preferably the listed order:

  • Finalize PHP 7.3 support (there is a nasty bug where Xdebug and a specific OPcache optimisation setting conflict).

  • Code needs to be reorganised, as the current location of source files and functions is detrimental to improvements.

  • The number of configuration options needs to be reduced.

  • Modes needs to be introduced, so that it is easier to turn off and on (internal) code to support different features. This will very likely improve general performance already.

  • Specific code paths and features need to be optimised. This includes primarily the basic features (stack traces, var_dump() improvements, etc.), as well as Code Coverage.

What is Needed to Get This Done?

I would love to be able to continue to work on Xdebug; to keep it in sync with changes in PHP itself, to implement the ideas from this article to improve the Xdebug Experience, and to produce educational material such as improved documentation, tutorials, and videos. (Dare I say a book?)

Therefore I am currently looking for ways that I can be funded for doing all the required work. It will take a lot of time to get Xdebug 3 out in a tip-top shape. Possibly, if not more, than 6 months. Although I have plenty of time now that I've left MongoDB, the bills and mortgage do need to get paid too. I can think of a few options:

  • Get more users to sign up to my Patreon account. There is a group of loyal users and companies that contribute towards the upkeep of the server. But in order to make this sustainable, the patron count need to increase about 30 fold. I struggle with setting up rewards to nudge people to support me.

  • A fundraiser (through a crowd funding site) for specific tasks and/or features from the plan.

  • Some functionality that would only be available under a commercial license. One of the ideas here is to add a recording feature that records the full execution of a script, which then later can be replayed back through an interactive single step debugging session in an IDE.

  • Work with IDE manufacturers to implement some of their requested features (such as the before mentioned "resolved breakpoint" notification), and to come up with new features to make the debugging experience better.

I am interested to hear whether you have a specific preference, or perhaps some additional suggestions for me to consider. I would absolutely want to give Xdebug all the love it still deserves after 17 years. Let me know what you think! Either in a comment, or by email.

cheers, Derick

Shortlink

This article has a short URL available: https://drck.me/xdebug-experience-eoy

Comments

I don't do Patreon, but I do want to contribute. Are there other ways? Paypal?

I love Xdebug as it is. Because it's so useful, not because it's no easy. Everybody should use it. Making it easier and faster would be a great start!

Hi Derick. I'd be interested to hear why each new version of PHP requires specific support in Xdebug, rather than "just working". Maybe you could do a post on that? :)

Im in! Will support this undertaking.

Xdebug is key to almost everything I do in PHP, and I use it everyday. Without it, PHP would not have the same value to me, and I'm not sure that I would even continue using PHP. IMO, it is critical that Xdebug's core functionality remains FOSS, though I understand the need for a sustainable model.

I have seen some other developers struggle to get started with Xdebug, even though they really want to use it. In order to get a larger userbase, it may be worthwhile to consider ease-of-use so that a beginner has some intuition as to why Xdebug is not working for them if it is not configured correctly.

I signed up on Patreon. If anyone sees this and are at all interested in the future of PHP, I encourage you to do the same.

Throw up both Bitcoin and Ethereum addresses. I'll donate.

I propose that you work on making it mindnumbingly easy to use xdebug. You say that you talked to users who mention that it’s too difficult to set up, and that you always concluded that it was caused by external tools or IDEs, but I think how you should treat these comments is to see it as a signal from the user that it’s actually not so easy to start using the software.

For example, if you go and have a look at the Reddit thread about this post, you will see that some of the most highly voted comments are about how people try to use xdebug but gave up. Basically, I think you should treat that as being unacceptable. Potential users not being able to use your software is bad for you and bad for them.

Perhaps it’s an idea to store all related settings into a JSON file, that people could commit to their repositories? At the first start up this JSON file can then be read and used to set up xdebug? Or perhaps it’s better to investigate some sort of server-client procedure with a configuration exchange in the beginning of a new connection? I don’t know. I am not familiar enough with the internals to make a good suggestion here.

I just think that it should be much easier to start using your software, it should basically be so simple that an idiot can do it with his eyes closed, every time, without fail, and without doing any configuration. Just my 2 cents. Thanks for all your great work over the years!

I subscribed to Patreon for an 5 USD per month support. Thank you for your support.

Hi Derick,

I was wondering if you could set up a corporate sponsors page on your site where we can have a small banner and a link if we pay you a monthly fee?

What do you think?

Cheers

Nolwenn

Hi!

Thanks for all the comments, I'll reply to them all in this comment of my own:

@Rudie: I don't have PayPal, as they're keen on holding on to money without telling me why, and making me wait for it. I am imploring whether I can sell licences, but that will likely have to be done more formally (with an invoice, and a bank transfer, or something like that).

@Jonathan: Each PHP version changes the internals of the language. Xdebug needs to dive deep into these internals to be able to do what it does. I can explain that better with a real example, and will endeavour to write a post when this happens the next time—I already know there are a few changes needed for PHP 7.4.

@Theodore: I don't know how Bitcoin and/or Ethereum work really. I might consider looking at that in the future, but right now, I don't have any plans to create accounts and wallets for them.

@Zach, @Ed, and @Robbert: Thanks for your comments.

@Nolwenn: Thanks for the suggestion. I have no plans to create an area where I provide links to companies that want to sponsor. I have already received many of these requests in the past, and most of them were dodgy outfits. Because I don't really want to say yes to some, and no to others, I have long ago decided that I don't want to go this route.

cheers,

Derick

Would be great if we could buy some cool Xdebug elephants!

Have you considered https://leanpub.com?

@Willem: Yes, that would be nice, but it's also a lot of work, and I'm not sure for how much gain...

@Stephen: Yes, I have heard of leanpub.com, and if I would do a bit, I would likely go that route.

Re: Modes: Have you considered splitting xdebug into different modules?

Profiler and debugger are not intended to be run together, even though they share a lot of common code. Which would reduce configuration issue by a lot.

I already used to use a wrapper to run scripts with debugger loaded, so that my regular maintenance tasks aren't influenced by xdebug. It just works, like if I'm running a different SAPI.

The easiest way to setup xdebug with docker is to realise that localhost is relative and 127.001 is too. Therefore what I have done in the past is create an ip alias on your machine to a pretty obscure ip nobody would use, like 10.254.254.254 and then inside your docker container, target that instead of localhost or trying to set your machines ip address which can change on a daily/hotspot basis.

What this does is mean you have a static local ip address you can know it'll always be free and then if you target port 9001 or whatever port you prefer, then you can easily setup your local IDE to receive connections.

If you try to do this any other way, you'll just run into a cloud of other problems.

To add an ip alias, do this. MacOs: sudo ifconfig lo0 alias 10.254.254.254 Linux: sudo ip addr add 10.254.254.254/24 dev lo label lo:40

Then in our docker container we set all sorts of environment variables to set the data inside the phpfpm container

we have a script which we run in our entrypoint which does sed-replaces of all the environment variables into the xdebug.ini file, the code looks like this: entrypoint.sh:

#!/usr/bin/env sh

# Configure XDebug
XDEBUG_INI=/usr/local/etc/php/conf.d/xdebug.ini

if [[ "${XDEBUG_ENABLE}" == "1" ]]; then
    echo "Enabling XDebug Configuration"
    # we use tilde ~ here instead of / because of path names
    sed -i "s~__XDEBUG_IDE_KEY__~${XDEBUG_IDE_KEY}~g" ${XDEBUG_INI}
    sed -i "s~__XDEBUG_ENABLE__~${XDEBUG_ENABLE}~g" ${XDEBUG_INI}
    sed -i "s~__XDEBUG_AUTOSTART__~${XDEBUG_AUTOSTART}~g" ${XDEBUG_INI}
    sed -i "s~__XDEBUG_HOST__~${XDEBUG_HOST}~g" ${XDEBUG_INI}
    sed -i "s~__XDEBUG_PORT__~${XDEBUG_PORT}~g" ${XDEBUG_INI}
    sed -i "s~__XDEBUG_LOG_DIR__~${XDEBUG_LOG_DIR}~g" ${XDEBUG_INI}
    sed -i "s~__XDEBUG_PROFILER_ENABLE__~${XDEBUG_PROFILER_ENABLE}~g" ${XDEBUG_INI}
    sed -i "s~__XDEBUG_PROFILER_ENABLE_TRIGGER__~${XDEBUG_PROFILER_ENABLE_TRIGGER}~g" ${XDEBUG_INI}
    sed -i "s~__XDEBUG_PROFILER_ENABLE_TRIGGER_VALUE__~${XDEBUG_PROFILER_ENABLE_TRIGGER_VALUE}~g" ${XDEBUG_INI}
    sed -i "s~__XDEBUG_PROFILER_OUTPUT_DIR__~${XDEBUG_PROFILER_OUTPUT_DIR}~g" ${XDEBUG_INI}

    echo "" > ${XDEBUG_LOG_DIR}/xdebug.log
    chown www-data:www-data ${XDEBUG_LOG_DIR}/xdebug.log
    chmod 775 ${XDEBUG_LOG_DIR}/xdebug.log

    # we need write permissions to write the cachegrind files that the profiler generates
    if [[ "${XDEBUG_PROFILER_ENABLE_TRIGGER}" == "1" ]] || [[ "${XDEBUG_PROFILER_ENABLE}" == "1" ]]; then
        chown www-data:www-data ${XDEBUG_PROFILER_OUTPUT_DIR}
        chmod 775 ${XDEBUG_PROFILER_OUTPUT_DIR}
    fi
else
    echo "Disabling XDebug Configuration"
    rm -f ${XDEBUG_INI}
    rm -f ${XDEBUG_LOG_DIR}/xdebug.log
fi

our xdebug.ini looks like this:

[xdebug]
zend_extension = xdebug.so

xdebug.idekey=__XDEBUG_IDE_KEY__
xdebug.overload_var_dump=0
xdebug.var_display_max_depth=10
xdebug.cli_color=1

xdebug.remote_connect_back=0
xdebug.remote_autostart=__XDEBUG_AUTOSTART__
xdebug.remote_enable=__XDEBUG_ENABLE__
; Do not change this token in the repository its replaced by the entrypoint with your machines current ip
; If you change networks, wifi, etc, your computers ip address may change and this requires a restart of the container
xdebug.remote_host=__XDEBUG_HOST__
; Do not change this port, but you cannot use port 9000, because php-fpm is using that
xdebug.remote_port=__XDEBUG_PORT__
xdebug.remote_log=__XDEBUG_LOG_DIR__/xdebug.log

xdebug.profiler_enable=__XDEBUG_PROFILER_ENABLE__
xdebug.profiler_enable_trigger=__XDEBUG_PROFILER_ENABLE_TRIGGER__
xdebug.profiler_enable_trigger_value=__XDEBUG_PROFILER_ENABLE_TRIGGER_VALUE__
xdebug.profiler_output_dir=__XDEBUG_PROFILER_OUTPUT_DIR__

xdebug.auto_trace=0
xdebug.collect_params=4
xdebug.show_mem_delta=1
xdebug.trace_enable_trigger=1
xdebug.trace_output_dir=__XDEBUG_LOG_DIR__

This setup works really well for us. I hope it helps other people having an easier time setting up their xdebug with dockder

Add Comment

Name:
Email:

Will not be posted. Please leave empty instead of filling in garbage though!
Comment:

Please follow the reStructured Text format. Do not use the comment form to report issues in software, use the relevant issue tracker. I will not answer them here.


All comments are moderated