Index: trunk/core/kernel/utility/debugger.php =================================================================== diff -u -N -r4859 -r4880 --- trunk/core/kernel/utility/debugger.php (.../debugger.php) (revision 4859) +++ trunk/core/kernel/utility/debugger.php (.../debugger.php) (revision 4880) @@ -1,56 +1,13 @@ $rq_value) { - if (substr($rq_name, 0, 6) == 'debug_') { - dbg_safeDefine('DBG_ZEND_PRESENT', 1); - break; - } - } - - dbg_safeDefine('DBG_ZEND_PRESENT', 0); // set this constant value to 0 (zero) to debug debugger using Zend Studio - - // set default values for debugger constants - $dbg_constMap = Array( - /*'DBG_OPTIONS' => 0,*/ - 'DBG_USE_HIGHLIGHT' => 1, // highlight output same as php code using "highlight_string" function - 'DBG_WINDOW_WIDTH' => 700, // set width of debugger window (in pixels) for better viewing large amount of debug data - 'DBG_USE_SHUTDOWN_FUNC' => DBG_ZEND_PRESENT ? 0 : 1, // use shutdown function to include debugger code into output - 'DBG_HANDLE_ERRORS' => DBG_ZEND_PRESENT ? 0 : 1, // handle all allowed by php (see php manual) errors instead of default handler - 'DBG_IGNORE_STRICT_ERRORS' => 1, // ignore PHP5 errors about private/public view modified missing in class declarations - 'DBG_DOMVIEWER' => '/temp/domviewer.html', // path to DOMViewer on website - 'DOC_ROOT' => str_replace('\\', '/', realpath($_SERVER['DOCUMENT_ROOT']) ), // windows hack - 'DBG_LOCAL_BASE_PATH' => 'w:' // replace DOC_ROOT in filenames (in errors) using this path - ); - - foreach ($dbg_constMap as $dbg_constName => $dbg_constValue) { - dbg_safeDefine($dbg_constName, $dbg_constValue); - } - - // only for IE, in case if no windows php script editor defined - /*if (!defined('DBG_EDITOR')) { - $dbg_editor = 0; - $dbg_editors[0] = Array('editor' => 'c:\Program Files\UltraEdit\uedit32.exe', 'params' => '%F/%L'); - $dbg_editors[1] = Array('editor' => 'c:\Program Files\Zend\ZendStudio-5.2.0\bin\ZDE.exe', 'params' => '%F'); - define('DBG_EDITOR', $dbg_editors[$dbg_editor]['editor'].' '.$dbg_editors[$dbg_editor]['params']); - unset($dbg_editors, $dbg_editor); - }*/ - class Debugger { + /** + * Set to true if fatal error occured + * + * @var bool + */ var $IsFatalError = false; /** @@ -59,6 +16,7 @@ * @var Array */ var $Data = Array(); + var $ProfilerData = Array(); var $ProfilerTotals = Array(); var $ProfilerTotalCount = Array(); @@ -70,9 +28,6 @@ */ var $RecursionStack = Array(); - var $Options = 0; - var $OptionsMap = Array('shutdown_func' => 1, 'error_handler' => 2, 'output_buffer' => 4, 'highlight_output' => 8); - var $scrollbarWidth = 0; /** @@ -82,14 +37,6 @@ */ var $longErrors = Array(); - /** - * Amount of memory used by debugger itself - * - * @var Array - * @access private - */ - var $memoryUsage = Array(); - var $IncludesData = Array(); var $IncludeLevel = 0; @@ -127,16 +74,69 @@ function Debugger() { global $start; + + $this->InitDebugger(); $this->profileStart('kernel4_startup', 'Startup and Initialization of kernel4', $start); $this->profileStart('script_runtime', 'Script runtime', $start); - ini_set('display_errors', dbg_ConstOn('DBG_ZEND_PRESENT') ? 0 : 1); // show errors on screen in case if not in Zend Studio debugging - $this->memoryUsage['error_handling'] = 0; // memory amount used by error handler + ini_set('display_errors', $this->constOn('DBG_ZEND_PRESENT') ? 0 : 1); // show errors on screen in case if not in Zend Studio debugging $this->scrollbarWidth = $this->isGecko() ? 22 : 25; // vertical scrollbar width differs in Firefox and other browsers $this->appendRequest(); } + /** + * Set's default values to constants debugger uses + * + */ + function InitDebugger() + { + unset($_REQUEST['debug_host'], $_REQUEST['debug_fastfile']); // this var messed up whole detection stuff :( + + // Detect fact, that this session beeing debugged by Zend Studio + foreach ($_REQUEST as $rq_name => $rq_value) { + if (substr($rq_name, 0, 6) == 'debug_') { + $this->safeDefine('DBG_ZEND_PRESENT', 1); + break; + } + } + + $this->safeDefine('DBG_ZEND_PRESENT', 0); // set this constant value to 0 (zero) to debug debugger using Zend Studio + + // set default values for debugger constants + $dbg_constMap = Array( + 'DBG_USE_HIGHLIGHT' => 1, // highlight output same as php code using "highlight_string" function + 'DBG_WINDOW_WIDTH' => 700, // set width of debugger window (in pixels) for better viewing large amount of debug data + 'DBG_USE_SHUTDOWN_FUNC' => DBG_ZEND_PRESENT ? 0 : 1, // use shutdown function to include debugger code into output + 'DBG_HANDLE_ERRORS' => DBG_ZEND_PRESENT ? 0 : 1, // handle all allowed by php (see php manual) errors instead of default handler + 'DBG_IGNORE_STRICT_ERRORS' => 1, // ignore PHP5 errors about private/public view modified missing in class declarations + 'DBG_DOMVIEWER' => '/temp/domviewer.html', // path to DOMViewer on website + 'DOC_ROOT' => str_replace('\\', '/', realpath($_SERVER['DOCUMENT_ROOT']) ), // windows hack + 'DBG_LOCAL_BASE_PATH' => 'w:' // replace DOC_ROOT in filenames (in errors) using this path + ); + + // only for IE, in case if no windows php script editor defined + if (!defined('DBG_EDITOR')) { +// $dbg_constMap['DBG_EDITOR'] = 'c:\Program Files\UltraEdit\uedit32.exe %F/%L'; + $dbg_constMap['DBG_EDITOR'] = 'c:\Program Files\Zend\ZendStudio-5.2.0\bin\ZDE.exe %F'; + } + + foreach ($dbg_constMap as $dbg_constName => $dbg_constValue) { + $this->safeDefine($dbg_constName, $dbg_constValue); + } + } + + function constOn($const_name) + { + return defined($const_name) && constant($const_name); + } + + function safeDefine($const_name, $const_value) { + if (!defined($const_name)) { + define($const_name, $const_value); + } + } + function InitReport() { if (!class_exists('kApplication')) return false; @@ -161,34 +161,7 @@ $this->longErrors[$key] = $msg; return $key; } - - /*function initOptions() - { - - } - - function setOption($name, $value) - { - if (!isset($this->OptionsMap[$name])) { - die('undefined debugger option: ['.$name.']
'); - } - - if ($value) { - $this->Options |= $this->OptionsMap[$name]; - } - else { - $this->Options = $this->Options &~ $this->OptionsMap[$name]; - } - } - - function getOption($name) - { - if (!isset($this->OptionsMap[$name])) { - die('undefined debugger option: ['.$name.']
'); - } - return ($this->Options & $this->OptionsMap[$name]) == $this->OptionsMap[$name]; - }*/ - + /** * Appends all passed variable values (wihout variable names) to debug output * @@ -384,7 +357,7 @@ function highlightString($string) { - if (!dbg_ConstOn('DBG_USE_HIGHLIGHT')) { + if (!$this->constOn('DBG_USE_HIGHLIGHT')) { return $string; } @@ -672,54 +645,54 @@ return ''; } - if (dbg_ConstOn('DBG_SKIP_REPORTING') || dbg_ConstOn('DBG_ZEND_PRESENT')) return ''; - + if ($this->constOn('DBG_SKIP_REPORTING') || $this->constOn('DBG_ZEND_PRESENT')) return ''; + + $debugger_start = memory_get_usage(); + if (defined('SPACER_URL')) { $this->dummyImage = SPACER_URL; } $this->InitReport(); // set parameters required by AJAX // defined here, because user can define this contant while script is running, not event before debugger is started - dbg_safeDefine('DBG_RAISE_ON_WARNINGS', 0); - - $this->memoryUsage['debugger_start'] = memory_get_usage(); + $this->safeDefine('DBG_RAISE_ON_WARNINGS', 0); $this->appendSession(); // show php session if any // ensure, that 1st line of debug output always is this one: $this->appendHTML('[Reload Frame] [Hide Debugger] [Current Time: '.date('H:i:s').']'); $this->moveToBegin(1); - if (dbg_ConstOn('DBG_SQL_PROFILE') && isset($this->ProfilerTotals['sql'])) { + if ($this->constOn('DBG_SQL_PROFILE') && isset($this->ProfilerTotals['sql'])) { // sql query profiling was enabled -> show totals $this->appendHTML('SQL Total time: '.$this->ProfilerTotals['sql'].' Number of queries: '.$this->ProfilerTotalCount['sql']); } - if (dbg_ConstOn('DBG_PROFILE_INCLUDES') && isset($this->ProfilerTotals['includes'])) { + if ($this->constOn('DBG_PROFILE_INCLUDES') && isset($this->ProfilerTotals['includes'])) { // included file profiling was enabled -> show totals $this->appendHTML('Included Files Total time: '.$this->ProfilerTotals['includes'].' Number of includes: '.$this->ProfilerTotalCount['includes']); } - if (dbg_ConstOn('DBG_PROFILE_MEMORY')) { + if ($this->constOn('DBG_PROFILE_MEMORY')) { // detailed memory usage reporting by objects was enabled -> show totals $this->appendHTML('Memory used by Objects: '.round($this->ProfilerTotals['objects'] / 1024, 2).'Kb'); } - /*if (dbg_ConstOn('DBG_INCLUDED_FILES')) { + /*if ($this->constOn('DBG_INCLUDED_FILES')) { $files = get_included_files(); $this->appendHTML('Included files:'); foreach ($files as $file) { $this->appendHTML($this->getFileLink($this->getLocalFile($file)).' ('.round(filesize($file) / 1024, 2).'Kb)'); } }*/ - /*if (dbg_ConstOn('DBG_PROFILE_INCLUDES')) { - $this->appendHTML('Included files statistics:'.( dbg_ConstOn('DBG_SORT_INCLUDES_MEM') ? ' (sorted by memory usage)':'')); + /*if ($this->constOn('DBG_PROFILE_INCLUDES')) { + $this->appendHTML('Included files statistics:'.( $this->constOn('DBG_SORT_INCLUDES_MEM') ? ' (sorted by memory usage)':'')); $totals = Array( 'mem' => 0, 'time' => 0); $totals_configs = Array( 'mem' => 0, 'time' => 0); if (is_array($this->IncludesData['mem'])) { - if ( dbg_ConstOn('DBG_SORT_INCLUDES_MEM') ) { + if ( $this->constOn('DBG_SORT_INCLUDES_MEM') ) { array_multisort($this->IncludesData['mem'], SORT_DESC, $this->IncludesData['file'], $this->IncludesData['time'], $this->IncludesData['level']); } foreach ($this->IncludesData['file'] as $key => $file_name) { @@ -777,30 +750,26 @@ window.focus(); memoryUsage['debugger_finish'] = memory_get_usage(); - $this->memoryUsage['print_report'] = $this->memoryUsage['debugger_finish'] - $this->memoryUsage['debugger_start']; - $this->memoryUsage['total'] = $this->memoryUsage['print_report'] + $this->memoryUsage['error_handling']; - $this->memoryUsage['application'] = memory_get_usage() - $this->memoryUsage['total']; - $this->memoryUsage['debugfile_size'] = filesize($debug_file); + $memory_used = $debugger_start - $this->ProfilerTotals['error_handling']; if ($returnResult) { $ret = ob_get_contents(); if ($clean_output_buffer) { ob_clean(); } - $ret .= $this->getMemoryUsageReport(); + $ret .= $this->getShortReport($memory_used); $this->reportDone = true; return $ret; } else { - if (!dbg_ConstOn('DBG_HIDE_FULL_REPORT')) { + if (!$this->constOn('DBG_HIDE_FULL_REPORT')) { $this->breakOutofBuffering(); } elseif ($clean_output_buffer) { ob_clean(); } - echo $this->getMemoryUsageReport(); + echo $this->getShortReport($memory_used); $this->reportDone = true; } @@ -812,32 +781,29 @@ * @return string * @access private */ - function getMemoryUsageReport() + function getShortReport($memory_used) { $info = Array( - 'Application' => 'MEM:application', - 'Script runtime'=> 'PROFILE:script_runtime', - '-' => 'SEP:-', - 'printReport' => 'MEM:print_report', - 'saveError' => 'MEM:error_handling', - 'Debug Total' => 'MEM:total', - 'Debug FileSize'=> 'MEM:debugfile_size' + 'Script Runtime' => 'PROFILE:script_runtime', + '-' => 'SEP:-', + 'Notice / Warning' => 'PROFILE_TC:error_handling', + 'SQLs Count' => 'PROFILE_TC:sql', ); - $ret = ''; + $ret = 'Application:'.$this->formatSize($memory_used).' ('.$memory_used.')'; foreach ($info as $title => $value_key) { list ($record_type, $record_data) = explode(':', $value_key, 2); switch ($record_type) { - case 'MEM': - $ret .= ''.$title.':'.$this->formatSize($this->memoryUsage[$record_data]).' ('.$this->memoryUsage[$record_data].')'; - break; - - case 'PROFILE': + case 'PROFILE': // profiler totals value $Data =& $this->ProfilerData[$record_data]; $profile_time = ($Data['ends'] - $Data['begins']); // in seconds - $ret .= ''.$title.':'.sprintf('%.5f', $profile_time).'s'; + $ret .= ''.$title.':'.sprintf('%.5f', $profile_time).' s'; break; - + + case 'PROFILE_TC': // profile totals record count + $ret .= ''.$title.':'.$this->ProfilerTotalCount[$record_data].''; + break; + case 'SEP': $ret .= ''; break; @@ -859,16 +825,15 @@ */ function saveError($errno, $errstr, $errfile = '', $errline = '', $errcontext = '') { - $memory_used = Array(); - $memory_used['begin'] = memory_get_usage(); + $this->ProfilerData['error_handling']['begins'] = memory_get_usage(); $errorType = $this->getErrorNameByCode($errno); if (!$errorType) { trigger_error('Unknown error type ['.$errno.']', E_USER_ERROR); return false; } - if (dbg_ConstOn('DBG_IGNORE_STRICT_ERRORS') && defined('E_STRICT') && ($errno == E_STRICT)) return; + if ($this->constOn('DBG_IGNORE_STRICT_ERRORS') && defined('E_STRICT') && ($errno == E_STRICT)) return; if (preg_match('/(.*)#([\d]+)$/', $errstr, $rets) ) { // replace short message with long one (due triger_error limitations on message size) @@ -887,13 +852,13 @@ } $this->Data[] = Array('no' => $errno, 'str' => $errstr, 'file' => $errfile, 'line' => $errline, 'context' => $errcontext, 'debug_type' => 'error'); - $memory_used['end'] = memory_get_usage(); - $this->memoryUsage['error_handling'] += $memory_used['end'] - $memory_used['begin']; + $this->ProfilerData['error_handling']['ends'] = memory_get_usage(); + $this->profilerAddTotal('error_handling', 'error_handling'); if (substr($errorType, 0, 5) == 'Fatal') { $this->breakOutofBuffering(false); $this->IsFatalError = true; if (ob_get_level()) ob_flush(); - if (!dbg_ConstOn('DBG_USE_SHUTDOWN_FUNC')) { + if (!$this->constOn('DBG_USE_SHUTDOWN_FUNC')) { $this->printReport(); } exit; @@ -963,7 +928,7 @@ } function AttachToApplication() { - if (!dbg_ConstOn('DBG_HANDLE_ERRORS')) return true; + if (!$this->constOn('DBG_HANDLE_ERRORS')) return true; if (class_exists('kApplication')) { restore_error_handler(); @@ -972,7 +937,7 @@ $application->errorHandlers[] = Array(&$this, 'saveError'); } else { - set_error_handler( Array(&$this, 'saveError') ); + set_error_handler(Array(&$this, 'saveError')); } } } @@ -981,11 +946,11 @@ function memory_get_usage(){ return -1; } } - if(!dbg_ConstOn('DBG_ZEND_PRESENT')) { + if (!Debugger::constOn('DBG_ZEND_PRESENT')) { $debugger = new Debugger(); } - if (dbg_ConstOn('DBG_USE_SHUTDOWN_FUNC')) { + if (Debugger::constOn('DBG_USE_SHUTDOWN_FUNC')) { register_shutdown_function( Array(&$debugger, 'printReport') ); } }