Stack Traces
When Xdebug is activated it will show a stack trace whenever PHP decides to show a notice, warning, error etc. The information that stack traces display, and the way how they are presented, can be configured to suit your needs.
The stack traces that Xdebug shows on error situations (if display_errors is set to On in php.ini) are quite conservative in the amount of information that they show. This is because large amounts of information can slow down both the execution of the scripts and the rendering of the stack traces themselves in the browser. However, it is possible to make the stack traces show more detailed information with different settings.
Variables in Stack Traces
By default Xdebug will now show variable information in the stack traces that it produces. Variable information can take quite a bit of resources, both while collecting or displaying. However, in many cases it is useful that variable information is displayed, and that is why Xdebug has the setting xdebug.collect_params. The script below, in combination with what the output will look like with different values of this setting is shown in the example below.
The script
<?php
function foo( $a ) {
for ($i = 1; $i < $a['foo']; $i++) {
if ($i == 500000) xdebug_break();
}
}
set_time_limit(1);
$c = new stdClass;
$c->bar = 100;
$a = array(
42 => false, 'foo' => 912124,
$c, new stdClass, fopen( '/etc/passwd', 'r' )
);
foo( $a );
?>
The results
Different values for the xdebug.collect_params setting give different output, which you can see below:
( ! ) Fatal error: Maximum execution time of 1 second exceeded in /home/httpd/html/test/xdebug/docs/stack.php on line 34 | ||||
---|---|---|---|---|
Call Stack | ||||
# | Time | Memory | Function | Location |
1 | 0.0001 | 58564 | {main}( ) | ../stack.php:0 |
2 | 0.0004 | 62764 | foo( ) | ../stack.php:47 |
ini_set('xdebug.collect_params', '1');
( ! ) Fatal error: Maximum execution time of 1 second exceeded in /home/httpd/html/test/xdebug/docs/stack.php on line 31 | ||||
---|---|---|---|---|
Call Stack | ||||
# | Time | Memory | Function | Location |
1 | 0.0001 | 58132 | {main}( ) | ../stack.php:0 |
2 | 0.0004 | 62380 | foo( array(5) ) | ../stack.php:47 |
ini_set('xdebug.collect_params', '2');
( ! ) Fatal error: Maximum execution time of 1 second exceeded in /home/httpd/html/test/xdebug/docs/stack.php on line 31 | ||||
---|---|---|---|---|
Call Stack | ||||
# | Time | Memory | Function | Location |
1 | 0.0001 | 58564 | {main}( ) | ../stack.php:0 |
2 | 0.0004 | 62812 | foo( array(5) ) | ../stack.php:47 |
ini_set('xdebug.collect_params', '3');
( ! ) Fatal error: Maximum execution time of 1 second exceeded in /home/httpd/html/test/xdebug/docs/stack.php on line 31 | ||||
---|---|---|---|---|
Call Stack | ||||
# | Time | Memory | Function | Location |
1 | 0.0001 | 58564 | {main}( ) | ../stack.php:0 |
2 | 0.0004 | 62812 | foo( array (42 => FALSE, 'foo' => 912124, 43 => class stdClass { public $bar = 100 }, 44 => class stdClass { }, 45 => resource(2) of type (stream)) ) | ../stack.php:47 |
ini_set('xdebug.collect_params', '4');
( ! ) Fatal error: Maximum execution time of 1 second exceeded in /home/httpd/html/test/xdebug/docs/stack.php on line 31 | ||||
---|---|---|---|---|
Call Stack | ||||
# | Time | Memory | Function | Location |
1 | 0.0001 | 58132 | {main}( ) | ../stack.php:0 |
2 | 0.0004 | 62380 | foo( $a = array (42 => FALSE, 'foo' => 912124, 43 => class stdClass { public $bar = 100 }, 44 => class stdClass { }, 45 => resource(2) of type (stream)) ) | ../stack.php:47 |
Additional Information
On top of showing the values of variables that were passed to each function Xdebug can also optionally show information about selected superglobals by using the xdebug.dump_globals and xdebug.dump.* settings. The settings xdebug.dump_once and xdebug.dump_undefined slightly modify when and which information is shown from the available superglobals. With the xdebug.show_local_vars setting you can instruct Xdebug to show all variables available in the top-most stack level for a user defined function as well. The examples below show this (the script is used from the example above).
( ! ) Fatal error: Maximum execution time of 1 second exceeded in /home/httpd/html/test/xdebug/docs/stack.php on line 34 | ||||
---|---|---|---|---|
Call Stack | ||||
# | Time | Memory | Function | Location |
1 | 0.0001 | 58564 | {main}( ) | ../stack.php:0 |
2 | 0.0004 | 62764 | foo( ) | ../stack.php:47 |
ini_set('xdebug.collect_vars', 'on'); ini_set('xdebug.collect_params', '4'); ini_set('xdebug.dump_globals', 'on'); ini_set('xdebug.dump.SERVER', 'REQUEST_URI');
( ! ) Fatal error: Maximum execution time of 1 second exceeded in /home/httpd/html/test/xdebug/docs/stack.php on line 33 | ||||
---|---|---|---|---|
Call Stack | ||||
# | Time | Memory | Function | Location |
1 | 0.0001 | 58132 | {main}( ) | ../stack.php:0 |
2 | 0.0004 | 62436 | foo( ) | ../stack.php:47 |
Dump $_SERVER | ||||
$_SERVER['REQUEST_URI'] = | string '/test/xdebug/docs/stack.php?level=5' (length=35) |
ini_set('xdebug.collect_vars', 'on'); ini_set('xdebug.collect_params', '4'); ini_set('xdebug.dump_globals', 'on'); ini_set('xdebug.dump.SERVER', 'REQUEST_URI'); ini_set('xdebug.show_local_vars', 'on');
( ! ) Fatal error: Maximum execution time of 1 second exceeded in /home/httpd/html/test/xdebug/docs/stack.php on line 31 | |||||
---|---|---|---|---|---|
Call Stack | |||||
# | Time | Memory | Function | Location | |
1 | 0.0001 | 58132 | {main}( ) | ../stack.php:0 | |
2 | 0.0005 | 62588 | foo( ) | ../stack.php:47 | |
Dump $_SERVER | |||||
$_SERVER['REQUEST_URI'] = | string '/test/xdebug/docs/stack.php?level=6' (length=35) | ||||
Variables in local scope (#2) | |||||
$a = | array 42 => boolean false 'foo' => int 912124 43 => object(stdClass)[1] public 'bar' => int 100 44 => object(stdClass)[2] 45 => resource(2, stream) | ||||
$i = | int 275447 |
Filtering
Xdebug 2.6 introduces filtering capabilities for stack traces. A filter either includes, or excludes, paths or class name prefixes (namespaces). You can use a filter to prevent anything from a vendor directory to appear in a stack trace, or to only include classes from specific namespaces.
To set-up a filter that shows only functions and methods that either have no class name, or are prefixed with "Xdebug", you would call xdebug_set_filter() with:
Example:
xdebug_set_filter(
XDEBUG_FILTER_TRACING,
XDEBUG_NAMESPACE_WHITELIST,
[ '', 'Xdebug' ]
);
With this filter set-up, you will only see functions (without class) and all method calls of classes that start with "Xdebug". This includes built-in PHP functions (such as strlen()
) and calls to XdebugTest::bar()
. The filter does not enforce that "Xdebug" is the name of a namespace, and only does a strict character comparison from the start of the fully qualified class name. Add a \
to the prefix to make sure only classes in the Xdebug\
namespace are included.
The full documentation for the arguments to xdebug_set_filter() are described on its own documentation page.
Related Settings and Functions
- integer xdebug.cli_color = 0
- boolean xdebug.collect_includes = true
- integer xdebug.collect_params = 0
- boolean xdebug.collect_vars = false
- string xdebug.dump.* = Empty
- boolean xdebug.dump_globals = true
- boolean xdebug.dump_once = true
- boolean xdebug.dump_undefined = false
- string xdebug.file_link_format =
- string xdebug.filename_format = ...%s%n
- string xdebug.manual_url = http://www.php.net
- integer xdebug.show_error_trace = 0
- integer xdebug.show_exception_trace = 0
- integer xdebug.show_local_vars = 0
- integer xdebug.show_mem_delta = 0
- integer xdebug.var_display_max_children = 128
- integer xdebug.var_display_max_data = 512
- integer xdebug.var_display_max_depth = 3
- xdebug_get_declared_vars() : array
- xdebug_get_function_stack() : array
- xdebug_get_monitored_functions() : array
- xdebug_get_stack_depth() : int
- xdebug_print_function_stack() : void
- xdebug_start_function_monitor() : void
- xdebug_stop_function_monitor() : void
Settings
integer xdebug.cli_color = 0 #
Introduced in Xdebug >= 2.2
If this setting is 1, Xdebug will color var_dumps and stack traces output when in CLI mode and when the output is a tty. On Windows, the ANSICON tool needs to be installed.
If the setting is 2, then Xdebug will always color var_dumps and stack trace, no matter whether it's connected to a tty or whether ANSICON is installed. In this case, you might end up seeing escape codes.
See this article for some more information.
boolean xdebug.collect_includes = true #
This setting, defaulting to 1, controls whether Xdebug should write the filename used in include(), include_once(), require() or require_once() to the trace files.
integer xdebug.collect_params = 0 #
This setting, defaulting to 0, controls whether Xdebug should collect the parameters passed to functions when a function call is recorded in either the function trace or the stack trace.
The setting defaults to 0 because for very large scripts it may use huge amounts of memory and therefore make it impossible for the huge script to run. You can most safely turn this setting on, but you can expect some problems in scripts with a lot of function calls and/or huge data structures as parameters. Xdebug 2 will not have this problem with increased memory usage, as it will never store this information in memory. Instead it will only be written to disk. This means that you need to have a look at the disk usage though.
This setting can have four different values. For each of the values a different amount of information is shown. Below you will see what information each of the values provides. See also the introduction of the feature Stack Traces for a few screenshots.
Value | Argument Information Shown |
---|---|
0 | None. |
1 | Type and number of elements (f.e. string(6), array(8)). |
2 | Type and number of elements, with a tool tip for the full information 1. |
3 | Full variable contents (with the limits respected as set by xdebug.var_display_max_children, xdebug.var_display_max_data and xdebug.var_display_max_depth. |
4 | Full variable contents and variable name. |
5 | PHP serialized variable contents, without the name. |
1 in the CLI version of PHP it will not have the tool tip, nor in output files.
boolean xdebug.collect_vars = false #
This setting tells Xdebug to gather information about which variables are used in a certain scope. This analysis can be quite slow as Xdebug has to reverse engineer PHP's opcode arrays. This setting will not record which values the different variables have, for that use xdebug.collect_params. This setting needs to be enabled only if you wish to use xdebug_get_declared_vars().
string xdebug.dump.* = Empty #
* can be any of COOKIE, FILES, GET, POST, REQUEST, SERVER, SESSION. These seven settings control which data from the superglobals is shown when an error situation occurs.
Each of those php.ini setting can consist of a comma separated list of variables from this superglobal to dump, or *
for all of them. Make sure you do not add spaces in this setting.
In order to dump the REMOTE_ADDR and the REQUEST_METHOD when an error occurs, and all GET parameters, add these settings:
xdebug.dump.SERVER = REMOTE_ADDR,REQUEST_METHOD xdebug.dump.GET = *
boolean xdebug.dump_globals = true #
When this setting is set to true
, Xdebug adds the values of the super globals as configured through the xdebug.dump.* to on-screen stack traces and the error log (if enabled).
boolean xdebug.dump_once = true #
Controls whether the values of the superglobals should be dumped on all error situations (set to 0) or only on the first (set to 1).
boolean xdebug.dump_undefined = false #
If you want to dump undefined values from the superglobals you should set this setting to 1, otherwise leave it set to 0.
string xdebug.file_link_format = #
Introduced in Xdebug >= 2.1
This setting determines the format of the links that are made in the display of stack traces where file names are used. This allows IDEs to set up a link-protocol that makes it possible to go directly to a line and file by clicking on the filenames that Xdebug shows in stack traces. An example format might look like:
myide://%f@%l
The possible format specifiers are:
Specifier | Meaning |
---|---|
%f | the filename |
%l | the line number |
For various IDEs/OSses there are some instructions listed on how to make this work:
Firefox on Linux
- Open about:config
- Add a new boolean setting "network.protocol-handler.expose.xdebug" and set it to "false"
- Add the following into a shell script
~/bin/ff-xdebug.sh
:#! /bin/sh f=`echo $1 | cut -d @ -f 1 | sed 's/xdebug:\/\///'` l=`echo $1 | cut -d @ -f 2`
Add to that one of (depending whether you have komodo, gvim or netbeans):komodo $f -l $l
gvim --remote-tab +$l $f
netbeans "$f:$l"
- Make the script executable with
chmod +x ~/bin/ff-xdebug.sh
- Set the xdebug.file_link_format setting to
xdebug://%f@%l
Windows and netbeans
- Create the file
netbeans.bat
and save it in your path (C:\Windows
will work):@echo off setlocal enableextensions enabledelayedexpansion set NETBEANS=%1 set FILE=%~2 %NETBEANS% --nosplash --console suppress --open "%FILE:~19%" nircmd win activate process netbeans.exe
Note: Remove the last line if you don't have
nircmd
. - Save the following code as
netbeans_protocol.reg
:Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\netbeans] "URL Protocol"="" @="URL:Netbeans Protocol" [HKEY_CLASSES_ROOT\netbeans\DefaultIcon] @="\"C:\\Program Files\\NetBeans 7.1.1\\bin\\netbeans.exe,1\"" [HKEY_CLASSES_ROOT\netbeans\shell] [HKEY_CLASSES_ROOT\netbeans\shell\open] [HKEY_CLASSES_ROOT\netbeans\shell\open\command] @="\"C:\\Windows\\netbeans.bat\" \"C:\\Program Files\\NetBeans 7.1.1\\bin\\netbeans.exe\" \"%1\""
Note: Make sure to change the path to Netbeans (twice), as well as the
netbeans.bat
batch file if you saved it somewhere else thanC:\Windows\
. - Double click on the
netbeans_protocol.reg
file to import it into the registry. - Set the xdebug.file_link_format setting to
xdebug.file_link_format = "netbeans://open/?f=%f:%l"
string xdebug.filename_format = ...%s%n #
Introduced in Xdebug >= 2.6
This setting determines the format with which Xdebug renders filenames in HTML stack traces (default: ...%s%n
) and location information through the overloaded xdebug_var_dump() (default: %f
).
The possible format specifiers are listed in this table. The example output is rendered according to the full path /var/www/vendor/mail/transport/mta.php
.
Specifier | Meaning | Example Output |
---|---|---|
%a | Ancester: Two directory elements and filename | mail/transport/mta.php |
%f | Full path | /var/www/vendor/mail/transport/mta.php |
%n | Name: Only the file name | mta.php |
%p | Parent: One directory element and the filename | transport/mta.php |
%s | Directory separator | / on Linux, OSX and other Unix-like systems, \ on Windows |
string xdebug.manual_url = http://www.php.net #
Available in Xdebug < 2.2.1
This is the base url for the links from the function traces and error message to the manual pages of the function from the message. It is advisable to set this setting to use the closest mirror.
integer xdebug.show_error_trace = 0 #
Introduced in Xdebug >= 2.4
When this setting is set to 1, Xdebug will show a stack trace whenever an Error is raised - even if this Error is actually caught.
integer xdebug.show_exception_trace = 0 #
When this setting is set to 1, Xdebug will show a stack trace whenever an Exception or Error is raised - even if this Exception or Error is actually caught.
Error 'exceptions' were introduced in PHP 7.
integer xdebug.show_local_vars = 0 #
When this setting is set to something != 0 Xdebug's generated stack dumps in error situations will also show all variables in the top-most scope. Beware that this might generate a lot of information, and is therefore turned off by default.
integer xdebug.show_mem_delta = 0 #
When this setting is set to something != 0 Xdebug's human-readable generated trace files will show the difference in memory usage between function calls. If Xdebug is configured to generate computer-readable trace files then they will always show this information.
integer xdebug.var_display_max_children = 128 #
Controls the amount of array children and object's properties are shown when variables are displayed with either xdebug_var_dump(), xdebug.show_local_vars or through Function Trace.
To disable any limitation, use -1 as value.
This setting does not have any influence on the number of children that is send to the client through the Step Debugging feature.
integer xdebug.var_display_max_data = 512 #
Controls the maximum string length that is shown when variables are displayed with either xdebug_var_dump(), xdebug.show_local_vars or through Function Trace.
To disable any limitation, use -1 as value.
This setting does not have any influence on the number of children that is send to the client through the Step Debugging feature.
integer xdebug.var_display_max_depth = 3 #
Controls how many nested levels of array elements and object properties are when variables are displayed with either xdebug_var_dump(), xdebug.show_local_vars or through Function Trace.
The maximum value you can select is 1023. You can also use -1 as value to select this maximum number.
This setting does not have any influence on the number of children that is send to the client through the Step Debugging feature.
Functions
xdebug_get_declared_vars() : array #
Returns declared variables
Returns an array where each element is a variable name which is defined in the current scope. The setting xdebug.collect_vars needs to be enabled.
Example:
<?php
class strings {
static function fix_strings($a, $b) {
foreach ($b as $item) {
}
var_dump(xdebug_get_declared_vars());
}
}
strings::fix_strings(array(1,2,3), array(4,5,6));
?>
Returns:
array 0 => string 'a' (length=1) 1 => string 'b' (length=1) 2 => string 'item' (length=4)
In PHP versions before 5.1, the variable name "a" is not in the returned array, as it is not used in the scope where the function xdebug_get_declared_vars() is called in.
xdebug_get_function_stack() : array #
Returns information about the stack
Returns an array which resembles the stack trace up to this point. The example script:
Example:
<?php
class strings {
function fix_string($a)
{
var_dump(xdebug_get_function_stack());
}
function fix_strings($b) {
foreach ($b as $item) {
$this->fix_string($item);
}
}
}
$s = new strings();
$ret = $s->fix_strings(array('Derick'));
?>
Returns:
array 0 => array 'function' => string '{main}' (length=6) 'file' => string '/var/www/xdebug_get_function_stack.php' (length=63) 'line' => int 0 'params' => array empty 1 => array 'function' => string 'fix_strings' (length=11) 'class' => string 'strings' (length=7) 'file' => string '/var/www/xdebug_get_function_stack.php' (length=63) 'line' => int 18 'params' => array 'b' => string 'array (0 => 'Derick')' (length=21) 2 => array 'function' => string 'fix_string' (length=10) 'class' => string 'strings' (length=7) 'file' => string '/var/www/xdebug_get_function_stack.php' (length=63) 'line' => int 12 'params' => array 'a' => string ''Derick'' (length=8)
xdebug_get_monitored_functions() : array #
Returns information about monitored functions
Returns a structure which contains information about where the monitored functions were executed in your script. The following example shows how to use this, and the returned information:
Example:
<?php
/* Start the function monitor for strrev and array_push: */
xdebug_start_function_monitor( [ 'strrev', 'array_push' ] );
/* Run some code: */
echo strrev("yes!"), "\n";
echo strrev("yes!"), "\n";
var_dump(xdebug_get_monitored_functions());
xdebug_stop_function_monitor();
?>
Returns:
/tmp/monitor-example.php:10: array(2) { [0] => array(3) { 'function' => string(6) "strrev" 'filename' => string(24) "/tmp/monitor-example.php" 'lineno' => int(6) } [1] => array(3) { 'function' => string(6) "strrev" 'filename' => string(24) "/tmp/monitor-example.php" 'lineno' => int(8) } }
xdebug_get_stack_depth() : int #
Returns the current stack depth level
Returns the stack depth level. The main body of a script is level 0 and each include and/or function call adds one to the stack depth level.
xdebug_print_function_stack( string $message = "user triggered", int $options = 0 ) : void #
Displays the current function stack
Displays the current function stack, in a similar way as what Xdebug would display in an error situation.
The "message" argument allows you to replace the message in the header with your own.
Example:
<?php
function foo( $far, $out )
{
xdebug_print_function_stack( 'Your own message' );
}
foo( 42, 3141592654 );
?>
Returns:
( ! ) Xdebug: Your own message in /home/httpd/html/test/xdebug/print_function_stack.php on line 5 Call Stack # Time Memory Function Location 1 0.0006 653896 {main}( ) ../print_function_stack.php:0 2 0.0007 654616 foo( 42, 3141592654 ) ../print_function_stack.php:7 3 0.0007 654736 xdebug_print_function_stack ( 'Your own message' ) ../print_function_stack.php:5
The bitmask "options" allows you to configure a few extra options. The following options are currently supported:
XDEBUG_STACK_NO_DESC
- If this option is set, then the printed stack trace will not have a header. This is useful if you want to print a stack trace from your own error handler, as otherwise the printed location is where
xdebug_print_function_stack()
was called from.
xdebug_start_function_monitor( array $listOfFunctionsToMonitor ) : void #
Starts function monitoring
This function starts the monitoring of functions that were given in a list as argument to this function. Function monitoring allows you to find out where in your code the functions that you provided as argument are called from. This can be used to track where old, or, discouraged functions are used.
Example:
<?php
xdebug_start_function_monitor( [ 'strrev', 'array_push' ] );
?>
You can also add class methods and static methods to the array that defines which functions to monitor. For example, to catch static calls to DramModel::canSee and dynamic calls to Whisky->drink, you would start the monitor with:
Example:
<?php
xdebug_start_function_monitor( [ 'DramModel::canSee', 'Whisky->drink'] );
?>
The defined functions are case sensitive, and a dynamic call to a static method will not be caught.
xdebug_stop_function_monitor() : void #
Stops monitoring functions
This function stops the function monitor. In order to get the list of monitored functions, you need to use the xdebug_get_monitored_functions() function.