Index: branches/5.3.x/core/kernel/utility/debugger.php =================================================================== diff -u -N -r15977 -r16195 --- branches/5.3.x/core/kernel/utility/debugger.php (.../debugger.php) (revision 15977) +++ branches/5.3.x/core/kernel/utility/debugger.php (.../debugger.php) (revision 16195) @@ -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(); @@ -1617,7 +1615,6 @@ if ( $skip_reporting ) { // let debugger write report and then don't output anything - $this->reportDone = true; return ''; } @@ -1628,7 +1625,7 @@ 'FilterTypes' => $this->_filterTypes, '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']), @@ -1656,7 +1653,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 ) { @@ -1666,26 +1665,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 ''; @@ -1774,19 +1773,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); @@ -1795,7 +1824,7 @@ throw new Exception('Unknown error type [' . $errno . ']'); } elseif ( substr($errorType, 0, 5) == 'Fatal' ) { - $this->IsFatalError = true; + $this->_fatalErrorHash = $this->_getErrorHash($errfile, $errline); $this->appendTrace(4); } @@ -1813,9 +1842,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; @@ -1860,10 +1895,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); } /** @@ -1901,7 +1936,7 @@ * @return string * @access private */ - private function breakOutofBuffering($flush = true) + private function _breakOutOfBuffering($flush = true) { $buffer_content = Array (); while ( ob_get_level() ) { @@ -2049,6 +2084,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