From 6fb7f2bb97b18a7e3bd066d0d83bca1b1b81d2a0 Mon Sep 17 00:00:00 2001 From: Florian Pritz Date: Sat, 3 Jan 2015 17:21:35 +0100 Subject: Improve stacktrace generation (circular reference errors) var_export can't handle circular references which can happen in codeigniter's objects and if those get passed as arguments it will throw another fatal error and the actual trace will get lost. Signed-off-by: Florian Pritz --- index.php | 48 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 9 deletions(-) (limited to 'index.php') diff --git a/index.php b/index.php index abca7afb1..df12a670e 100644 --- a/index.php +++ b/index.php @@ -211,6 +211,44 @@ function _exception_handler($errno, $errstr, $errfile, $errline) } set_error_handler("_exception_handler"); +// Source: https://gist.github.com/abtris/1437966 +function getExceptionTraceAsString($exception) { + $rtn = ""; + $count = 0; + foreach ($exception->getTrace() as $frame) { + $args = ""; + if (isset($frame['args'])) { + $args = array(); + foreach ($frame['args'] as $arg) { + if (is_string($arg)) { + $args[] = "'" . $arg . "'"; + } elseif (is_array($arg)) { + $args[] = "Array"; + } elseif (is_null($arg)) { + $args[] = 'NULL'; + } elseif (is_bool($arg)) { + $args[] = ($arg) ? "true" : "false"; + } elseif (is_object($arg)) { + $args[] = get_class($arg); + } elseif (is_resource($arg)) { + $args[] = get_resource_type($arg); + } else { + $args[] = $arg; + } + } + $args = join(", ", $args); + } + $rtn .= sprintf( "#%s %s(%s): %s(%s)\n", + $count, + isset($frame['file']) ? $frame['file'] : 'unknown file', + isset($frame['line']) ? $frame['line'] : 'unknown line', + (isset($frame['class'])) ? $frame['class'].$frame['type'].$frame['function'] : $frame['function'], + $args ); + $count++; + } + return $rtn; +} + // The actual exception handler function _actual_exception_handler($e) { @@ -220,15 +258,7 @@ function _actual_exception_handler($e) $heading = "Internal Server Error"; $message = "

An unhandled error occured.

\n"; - $backtrace = ""; - $i = 0; - foreach ($e->getTrace() as $key => $frame) { - $backtrace .= sprintf("#%d %s(%d): %s(%s)\n", - $i++, isset($frame["file"]) ? $frame["file"] : "[internal function]", - isset($frame["line"]) ? $frame["line"] : "", $frame["function"], implode(", ", array_map( - function ($e) { return var_export($e, true); }, $frame["args"]))); - } - + $backtrace = getExceptionTraceAsString($e); if ($display_errors) { $message .= '
'; $message .= 'Fatal error: Uncaught exception '.get_class($e).'
'; -- cgit v1.2.3-24-g4f1b