Tracing things back to where they came from

One of the things I find myself doing a lot when developing WordPress is debugging things and so I spend a lot of time thinking of ways I can make this easier for me and easier for everyone else. Overtime this had led to a number of significant improvements to the debug ability of WordPress core including things like WP_DEBUG and the Deprecated Notices as well as the development of great tools like the Debug Bar plugin.

Recently I’ve found that the more context you can get to an issue the easier it is to understand and debug and I also noticed that while we recorded a simple backtrace for queries in core when SAVEQUERIES was defined we didn’t do a good job of presenting the data. Some function calls need more context that just the function name to be most useful – such as when running an action/filter it is useful to know the name and when requiring or including a file is useful to know the file name and some path context. This lead to the idea of refactoring the backtrace capture functionality out of WPDB and into a function that was improved to give proper calling syntax for functions in classes when called statically and was more obviously re-usable by plugins like the Debug Bar.

So today I have introduced wp_debug_backtrace_summary( $ignore_class = null, $skip_frames = 0, $pretty = true ) for #19589. If you provide no arguments you will get back string containing the full trace of the code run up to the place where you call wp_debug_backtrace_summary() – you won’t see the call to it in the trace as it always hides itself.

The best way to see the difference and improvements is to look at how this improves the information in the development version of the Debug Bar (new release coming soon) so after the break I have included some before and after screenshots.

Debug Bar query list before the change showing the previous limited infomation
Development version of the Debug Bar showing the enhanced details
An example of how the Debug Bar currently displays warnings, notices and deprecated function calls.
The development version of the Debug Bar showing how it can use this new function to display much more useful information

One of the things I suspect I will be doing a lot with this new function is dropping calls to error_log( wp_debug_backtrace_summary() ); into code that I am trying to debug and work out how often and from where it is being called.  In the past I’ve done this by using print_r( debug_backtrace() ); which prints out a lot of information (some of which is pretty useful) and more recently I’ve been using print_r( debug_backtrace( false ) ); so as to only fetch and print the stack traces.

Using this new function does mean I lose by using  the access to line numbers and file names I had from the raw PHP functions but I find that with the file names in the require/include calls and the function name being called I can get to the code just as fast as before.

I hope you all put this new function to good use!

8 thoughts on “Tracing things back to where they came from

  1. Small PHPDoc issue – $skip_frames is integer, but @param for it says string.

    Will be great to have in core, my custom debug functions keep organizing themselves in most chaotic way possible.

  2. I add backtrace to deprecation notice filters in my functions.php so I can find when plugins are using deprecated stuff. Needed because notices only tell you where in the core code the bad arg/func happened, but not the plugin that called the core code.

    Let’s see if this sample code will paste:

    function plugin_backtrace() {
    var_dump(debug_backtrace());
    }

    add_action( ‘deprecated_argument_run’, ‘plugin_backtrace’ );
    add_action( ‘deprecated_function_run’, ‘plugin_backtrace’ );

    1. Nice.

      With the development version of the Debug Bar you will get the simple backtrace for Deprecated function calls / includes too. Of course this only catches the ones on pages you interact with as a (Super) Admin user. Being able to find these more easily was one of the reasons this came about :)

Comments are closed.