diff --git a/examples/xdebug.php b/examples/xdebug.php new file mode 100644 index 000000000..fe73312a7 --- /dev/null +++ b/examples/xdebug.php @@ -0,0 +1,66 @@ + + + +

Tracy: exception demo

+ +second(true, false); + } + + + public function second($arg3, $arg4) + { + self::third([1, 2, 3]); + } + + + public static function third($arg5) + { + //require __DIR__ . '/assets/E_COMPILE_WARNING-1.php'; + //require __DIR__ . '/assets/E_COMPILE_ERROR.php'; +// trigger_error('jo', E_USER_ERROR); +// dump(new Exception); +// dumpe(xdebug_get_function_stack( [ 'local_vars' => true, 'params_as_values' => true ] )); + try { + throw new Exception('Original'); + } catch (Exception $e) { + throw new Exception('The my exception', 123, $e); + } + $a++; + } +} + + + +function demo($a, $b) +{ + $demo = new DemoClass; + $demo->first($a, $b); +} + + +if (Debugger::$productionMode) { + echo '

For security reasons, Tracy is visible only on localhost. Look into the source code to see how to enable Tracy.

'; +} + +demo(10, 'any string'); diff --git a/src/Tracy/BlueScreen/BlueScreen.php b/src/Tracy/BlueScreen/BlueScreen.php index 656058d67..7063bd060 100644 --- a/src/Tracy/BlueScreen/BlueScreen.php +++ b/src/Tracy/BlueScreen/BlueScreen.php @@ -499,4 +499,19 @@ private function findGeneratorsAndFibers(object $object): array Helpers::traverseValue($object, $add); return [$generators, $fibers]; } + + + public function getRealArgsAndVariables(\Throwable $exception): array + { + if ( + function_exists('xdebug_get_function_stack') + && version_compare(phpversion('xdebug'), '3.3.0', '>=') + && ($stack = xdebug_get_function_stack(['from_exception' => $exception])) // it must be an uncaught exception, not ie. ErrorException + ) { + $stack = array_slice(array_reverse($stack), 0, -1); + return [array_column($stack, 'params'), array_column($stack, 'variables')]; + } + + return [null, null]; + } } diff --git a/src/Tracy/BlueScreen/assets/bluescreen.css b/src/Tracy/BlueScreen/assets/bluescreen.css index bbe86c943..376ca0359 100644 --- a/src/Tracy/BlueScreen/assets/bluescreen.css +++ b/src/Tracy/BlueScreen/assets/bluescreen.css @@ -354,7 +354,7 @@ html.tracy-bs-visible body { position: relative; } -#tracy-bs .tracy-callstack-args tr:first-child td:before { +#tracy-bs .tracy-callstack-args-warning tr:first-child td:before { position: absolute; right: .3em; content: 'may not be true'; diff --git a/src/Tracy/BlueScreen/assets/section-stack-callStack.phtml b/src/Tracy/BlueScreen/assets/section-stack-callStack.phtml index 74b3744d8..55e8b18c7 100644 --- a/src/Tracy/BlueScreen/assets/section-stack-callStack.phtml +++ b/src/Tracy/BlueScreen/assets/section-stack-callStack.phtml @@ -8,6 +8,8 @@ namespace Tracy; * @var callable $dump * @var int $expanded * @var array $stack + * @var ?array $realArgs + * @var ?array $variables */ if (!$stack) { @@ -66,8 +68,38 @@ if (!$stack) { - + +

Arguments

+ + $v) { + echo '\n"; + } +?> +
', Helpers::escapeHtml((is_string($argName) ? '$' : '#') . $argName), ''; + echo $dump($v, $argName); + echo "
+ + +

Local Variables

+ + + $v) { + echo '\n"; + } +?> +
$', Helpers::escapeHtml($k), ''; + echo $dump($v, $k); + echo "
+ + + + +

Arguments

+ + getFile(); $line = $ex->getLine(); +[$realArgs, $variables] = $this->getRealArgsAndVariables($ex); require __DIR__ . '/section-stack-sourceFile.phtml'; +require __DIR__ . '/section-stack-variables.phtml'; require __DIR__ . '/section-stack-callStack.phtml'; diff --git a/src/Tracy/BlueScreen/assets/section-stack-variables.phtml b/src/Tracy/BlueScreen/assets/section-stack-variables.phtml new file mode 100644 index 000000000..055004193 --- /dev/null +++ b/src/Tracy/BlueScreen/assets/section-stack-variables.phtml @@ -0,0 +1,30 @@ + + +
+

Local variables

+ +
+
+ $v) { + echo '\n"; + } +?> +
$', Helpers::escapeHtml($k), ''; + echo $dump($v, $k); + echo "
+ + diff --git a/src/Tracy/Dumper/Describer.php b/src/Tracy/Dumper/Describer.php index e841a3fa4..f0d566ca9 100644 --- a/src/Tracy/Dumper/Describer.php +++ b/src/Tracy/Dumper/Describer.php @@ -327,7 +327,10 @@ private static function findLocation(): ?array $location = $item; continue; } elseif (isset($item['function'])) { - try { + $exists = isset($item['class']) + ? method_exists($item['class'], $item['function']) + : function_exists($item['function']); + if ($exists) { $reflection = isset($item['class']) ? new \ReflectionMethod($item['class'], $item['function']) : new \ReflectionFunction($item['function']); @@ -338,7 +341,6 @@ private static function findLocation(): ?array $location = $item; continue; } - } catch (\ReflectionException) { } }