Index: branches/5.2.x/core/kernel/utility/debugger.php =================================================================== diff -u -N -r15856 -r16140 --- branches/5.2.x/core/kernel/utility/debugger.php (.../debugger.php) (revision 15856) +++ branches/5.2.x/core/kernel/utility/debugger.php (.../debugger.php) (revision 16140) @@ -1,6 +1,6 @@ reportDone ) { + if ( $this->_inReportPrinting ) { // don't print same report twice (in case if shutdown function used + compression + fatal error) return ''; } + $this->_inReportPrinting = true; $last_error = error_get_last(); - if ( !is_null($last_error) && !$this->_lastErrorProcessed ) { - $this->_lastErrorProcessed = true; - $this->saveError($last_error['type'], $last_error['message'], $last_error['file'], $last_error['line']); + if ( !is_null($last_error) && $is_shutdown_func ) { + $this->saveError( + $last_error['type'], + $last_error['message'], + $last_error['file'], + $last_error['line'], + null, + $is_shutdown_func + ); } $this->profileFinish('script_runtime'); - $this->breakOutofBuffering(!$returnResult); + $this->_breakOutOfBuffering(!$return_result); $debugger_start = memory_get_usage(); @@ -1561,7 +1559,6 @@ if ( $skip_reporting ) { // let debugger write report and then don't output anything - $this->reportDone = true; return ''; } @@ -1571,7 +1568,7 @@ $debugger_params = Array ( 'RowSeparator' => $this->rowSeparator, 'ErrorsCount' => (int)$this->getProfilerTotal('error_handling'), - 'IsFatalError' => $this->IsFatalError, + 'IsFatalError' => $this->_fatalErrorHappened(), 'SQLCount' => (int)$this->getProfilerTotal('sql'), 'SQLTime' => isset($this->ProfilerTotals['sql']) ? sprintf('%.5f', $this->ProfilerTotals['sql']) : 0, 'ScriptTime' => sprintf('%.5f', $this->ProfilerData['script_runtime']['ends'] - $this->ProfilerData['script_runtime']['begins']), @@ -1599,7 +1596,9 @@ IsFatalError || (!$is_install && DBG_RAISE_ON_WARNINGS && $this->WarningCount) ) { + if ( $this->_fatalErrorHappened() + || (!$is_install && DBG_RAISE_ON_WARNINGS && $this->WarningCount) + ) { echo '$Debugger.Toggle();'; } if ( DBG_TOOLBAR_BUTTONS ) { @@ -1609,26 +1608,26 @@ window.focus(); getShortReport($this->getMemoryUsed($debugger_start)); - $this->reportDone = true; return $ret; } else { if ( !DebuggerUtil::constOn('DBG_HIDE_FULL_REPORT') ) { - $this->breakOutofBuffering(); + $this->_breakOutOfBuffering(); } elseif ( $clean_output_buffer ) { ob_clean(); } - echo $this->getShortReport($this->getMemoryUsed($debugger_start)); - $this->reportDone = true; + echo $this->getShortReport($this->getMemoryUsed($debugger_start)); } return ''; @@ -1706,19 +1705,49 @@ } /** - * User-defined error handler + * Detects if there was a fatal error at some point * - * @throws Exception - * @param int $errno - * @param string $errstr - * @param string $errfile - * @param int $errline - * @param array $errcontext - * @return bool - * @access public + * @return boolean */ - public function saveError($errno, $errstr, $errfile = null, $errline = null, $errcontext = Array ()) + private function _fatalErrorHappened() { + return $this->_fatalErrorHash !== 0; + } + + /** + * Creates error hash + * + * @param string $errfile File, where error happened. + * @param integer $errline Line in file, where error happened. + * + * @return integer + */ + private function _getErrorHash($errfile, $errline) + { + return crc32($errfile . ':' . $errline); + } + + /** + * User-defined error handler + * + * @param integer $errno Error code. + * @param string $errstr Error message. + * @param string $errfile Error file. + * @param integer $errline Error line. + * @param array $errcontext Error context. + * @param boolean $is_shutdown_func Called from shutdown function. + * + * @return boolean + * @throws Exception When unknown error code given. + */ + public function saveError( + $errno, + $errstr, + $errfile = null, + $errline = null, + array $errcontext = null, + $is_shutdown_func = false + ) { $this->ProfilerData['error_handling']['begins'] = memory_get_usage(); $errorType = $this->getErrorNameByCode($errno); @@ -1729,7 +1758,7 @@ return false; } elseif ( substr($errorType, 0, 5) == 'Fatal' ) { - $this->IsFatalError = true; + $this->_fatalErrorHash = $this->_getErrorHash($errfile, $errline); $this->appendTrace(4); } @@ -1747,9 +1776,15 @@ $this->WarningCount++; } - if ( $this->IsFatalError ) { - // append debugger report to data in buffer & clean buffer afterwards - die( $this->breakOutofBuffering(false) . $this->printReport(true) ); + if ( $this->_fatalErrorHappened() + && $this->_getErrorHash($errfile, $errline) === $this->_fatalErrorHash + ) { + // Append debugger report to data in buffer & clean buffer afterwards. + echo $this->_breakOutOfBuffering(false) . $this->printReport(true); + + if ( !$is_shutdown_func ) { + exit; + } } return true; @@ -1794,10 +1829,10 @@ public function saveException($exception) { $this->appendException($exception); - $this->IsFatalError = true; + $this->_fatalErrorHash = $this->_getErrorHash($exception->getFile(), $exception->getLine()); - // append debugger report to data in buffer & clean buffer afterwards - die( $this->breakOutofBuffering(false) . $this->printReport(true) ); + // Append debugger report to data in buffer & clean buffer afterwards. + echo $this->_breakOutOfBuffering(false) . $this->printReport(true); } /** @@ -1835,7 +1870,7 @@ * @return string * @access private */ - private function breakOutofBuffering($flush = true) + private function _breakOutOfBuffering($flush = true) { $buffer_content = Array (); while ( ob_get_level() ) { @@ -1983,6 +2018,6 @@ } if ( DebuggerUtil::constOn('DBG_USE_SHUTDOWN_FUNC') ) { - register_shutdown_function(Array (&$debugger, 'printReport')); + register_shutdown_function(array(&$debugger, 'printReport'), false, true, true); } - } \ No newline at end of file + }