Trying to debug PHP using its default current-line-only error messages is horrible. How can I get PHP to produce a backtrace (stack trace) when errors are produced?
+4
A:
My script for installing an error handler that produces a backtrace:
<?php
function process_error_backtrace($errno, $errstr, $errfile, $errline, $errcontext) {
if(!(error_reporting() & $errno))
return;
switch($errno) {
case E_WARNING :
case E_USER_WARNING :
case E_STRICT :
case E_NOTICE :
case E_USER_NOTICE :
$type = 'warning';
$fatal = false;
break;
default :
$type = 'fatal error';
$fatal = true;
break;
}
$trace = array_reverse(debug_backtrace());
array_pop($trace);
if(php_sapi_name() == 'cli') {
echo 'Backtrace from ' . $type . ' \'' . $errstr . '\' at ' . $errfile . ' ' . $errline . ':' . "\n";
foreach($trace as $item)
echo ' ' . (isset($item['file']) ? $item['file'] : '<unknown file>') . ' ' . (isset($item['line']) ? $item['line'] : '<unknown line>') . ' calling ' . $item['function'] . '()' . "\n";
} else {
echo '<p class="error_backtrace">' . "\n";
echo ' Backtrace from ' . $type . ' \'' . $errstr . '\' at ' . $errfile . ' ' . $errline . ':' . "\n";
echo ' <ol>' . "\n";
foreach($trace as $item)
echo ' <li>' . (isset($item['file']) ? $item['file'] : '<unknown file>') . ' ' . (isset($item['line']) ? $item['line'] : '<unknown line>') . ' calling ' . $item['function'] . '()</li>' . "\n";
echo ' </ol>' . "\n";
echo '</p>' . "\n";
}
if(ini_get('log_errors')) {
$items = array();
foreach($trace as $item)
$items[] = (isset($item['file']) ? $item['file'] : '<unknown file>') . ' ' . (isset($item['line']) ? $item['line'] : '<unknown line>') . ' calling ' . $item['function'] . '()';
$message = 'Backtrace from ' . $type . ' \'' . $errstr . '\' at ' . $errfile . ' ' . $errline . ': ' . join(' | ', $items);
error_log($message);
}
if($fatal)
exit(1);
}
set_error_handler('process_error_backtrace');
?>
Caveat: it is powerless to affect various 'PHP Fatal Errors', since Zend in their wisdom decided that these would ignore set_error_handler()
. So you still get useless final-location-only errors with those.
chaos
2009-07-21 13:37:06
+1
A:
$backtrace = debug_backtrace();
i wrote a little article about backtracing a while back
smoove666
2009-07-21 13:37:19
+8
A:
Xdebug prints a backtrace table on errors, and you don't have to write any PHP code to implement it.
Downside is you have to install it as a PHP extension.
patcoll
2009-07-21 13:50:37
I definitly recommend Xdebug too : I wouldn't imagine developping in PHP without it ! Just note that you should absolutly not install it on a production server : it's kinda hurting performances (and you don't, in theory, need that kind of information in a production server)
Pascal MARTIN
2009-07-21 17:50:14
This just saved me a real headache, thanks patcoll
Marc Roberts
2010-07-27 20:56:14
+1
A:
set_error_handler() + debug_backtrace()
( + debug_print_backtrace() in PHP5 )
Lukasz Czerwinski
2010-05-05 10:21:39