diff --git a/examples/xdebug.php b/examples/xdebug.php
new file mode 100644
index 000000000..2282d9203
--- /dev/null
+++ b/examples/xdebug.php
@@ -0,0 +1,66 @@
+
+
+
+
Tracy: exception demo
+
+second();
+ }
+
+
+ public function second()
+ {
+ 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..fb220a05b 100644
--- a/src/Tracy/BlueScreen/BlueScreen.php
+++ b/src/Tracy/BlueScreen/BlueScreen.php
@@ -499,4 +499,18 @@ private function findGeneratorsAndFibers(object $object): array
Helpers::traverseValue($object, $add);
return [$generators, $fibers];
}
+
+
+ public function getRealArgsAndVariables(\Throwable $exception): array
+ {
+ $args = $variables = [];
+ if (function_exists('xdebug_get_function_stack') && version_compare(phpversion('xdebug'), '3.3.0', '>=')) {
+ $stack = xdebug_get_function_stack(['from_exception' => $exception]);
+ foreach (array_reverse($stack) as $k => $row) {
+ $args[$k] = $row['params'] ?? [];
+ $variables[$k - 1] = $row['variables'] ?? [];
+ }
+ }
+ return [$args, $variables];
+ }
}
diff --git a/src/Tracy/BlueScreen/assets/bluescreen.css b/src/Tracy/BlueScreen/assets/bluescreen.css
index bbe86c943..f63c29569 100644
--- a/src/Tracy/BlueScreen/assets/bluescreen.css
+++ b/src/Tracy/BlueScreen/assets/bluescreen.css
@@ -350,11 +350,15 @@ html.tracy-bs-visible body {
grid-column-end: 3;
}
-#tracy-bs .tracy-callstack-args tr:first-child > * {
+#tracy-bs .tracy-callstack-args tr > :first-child {
+ width: 10em;
+}
+
+#tracy-bs .tracy-callstack-args-warning tr:first-child > * {
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..130dfa087 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,19 @@ if (!$stack) {
-
+
+ $v) {
+ echo '', Helpers::escapeHtml((is_string($argName) ? '$' : '#') . $argName), ' | ';
+ echo $dump($v, $argName);
+ echo " |
\n";
+ }
+?>
+
+
+
+
+
+
+ Local Variables
+
+
+ $v) {
+ echo '$', Helpers::escapeHtml($k), ' | ';
+ echo $dump($v, $k);
+ echo " |
\n";
+ }
+?>
+
+
diff --git a/src/Tracy/BlueScreen/assets/section-stack-exception.phtml b/src/Tracy/BlueScreen/assets/section-stack-exception.phtml
index 9e9bc66de..e3d459832 100644
--- a/src/Tracy/BlueScreen/assets/section-stack-exception.phtml
+++ b/src/Tracy/BlueScreen/assets/section-stack-exception.phtml
@@ -33,6 +33,8 @@ if (($stack[0]['class'] ?? null) === Debugger::class && in_array($stack[0]['func
}
$file = $ex->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..6fc766421
--- /dev/null
+++ b/src/Tracy/BlueScreen/assets/section-stack-variables.phtml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+ $v) {
+ echo '$', Helpers::escapeHtml($k), ' | ';
+ echo $dump($v, $k);
+ echo " |
\n";
+ }
+?>
+
+
+
diff --git a/src/Tracy/Dumper/Describer.php b/src/Tracy/Dumper/Describer.php
index e841a3fa4..a0d293c68 100644
--- a/src/Tracy/Dumper/Describer.php
+++ b/src/Tracy/Dumper/Describer.php
@@ -326,19 +326,19 @@ private static function findLocation(): ?array
if (isset($item['class']) && ($item['class'] === self::class || $item['class'] === Tracy\Dumper::class)) {
$location = $item;
continue;
- } elseif (isset($item['function'])) {
- try {
- $reflection = isset($item['class'])
- ? new \ReflectionMethod($item['class'], $item['function'])
- : new \ReflectionFunction($item['function']);
- if (
- $reflection->isInternal()
- || preg_match('#\s@tracySkipLocation\s#', (string) $reflection->getDocComment())
- ) {
- $location = $item;
- continue;
- }
- } catch (\ReflectionException) {
+ } elseif (
+ isset($item['function'])
+ && (isset($item['class']) ? method_exists($item['class'], $item['function']) : function_exists($item['function']))
+ ) {
+ $reflection = isset($item['class'])
+ ? new \ReflectionMethod($item['class'], $item['function'])
+ : new \ReflectionFunction($item['function']);
+ if (
+ $reflection->isInternal()
+ || preg_match('#\s@tracySkipLocation\s#', (string) $reflection->getDocComment())
+ ) {
+ $location = $item;
+ continue;
}
}