Skip to content

Commit

Permalink
bluescreen: displays real arguments and local variables [WIP]
Browse files Browse the repository at this point in the history
- requires xdebug 3.3 and xdebug.mode=develop
  • Loading branch information
dg committed Jan 2, 2024
1 parent 591e3e1 commit 14e0d01
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 4 deletions.
66 changes: 66 additions & 0 deletions examples/xdebug.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

declare(strict_types=1);

require __DIR__ . '/../src/tracy.php';

use Tracy\Debugger;

// For security reasons, Tracy is visible only on localhost.
// You may force Tracy to run in development mode by passing the Debugger::Development instead of Debugger::Detect.
//Debugger::$strictMode = true;
Debugger::enable(Debugger::Detect, __DIR__ . '/log');

?>
<!DOCTYPE html><link rel="stylesheet" href="assets/style.css">

<h1>Tracy: exception demo</h1>

<?php

class DemoClass
{
public function first($arg1, $arg2)
{
$arg1 = 'new';
$arg3 = 'xxx';
$this->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 '<p><b>For security reasons, Tracy is visible only on localhost. Look into the source code to see how to enable Tracy.</b></p>';
}

demo(10, 'any string');
15 changes: 15 additions & 0 deletions src/Tracy/BlueScreen/BlueScreen.php
Original file line number Diff line number Diff line change
Expand Up @@ -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];
}
}
2 changes: 1 addition & 1 deletion src/Tracy/BlueScreen/assets/bluescreen.css
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
34 changes: 33 additions & 1 deletion src/Tracy/BlueScreen/assets/section-stack-callStack.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ namespace Tracy;
* @var callable $dump
* @var int $expanded
* @var array $stack
* @var ?array $realArgs
* @var ?array $variables
*/

if (!$stack) {
Expand Down Expand Up @@ -66,8 +68,38 @@ if (!$stack) {
<?php endif ?>


<?php if (!empty($row['args'])): ?>
<?php if (!empty($realArgs[$key])): ?>
<h3>Arguments</h3>

<table class="tracy-callstack-args">
<?php
foreach ($realArgs[$key] as $argName => $v) {
echo '<tr><th>', Helpers::escapeHtml((is_string($argName) ? '$' : '#') . $argName), '</th><td>';
echo $dump($v, $argName);
echo "</td></tr>\n";
}
?>
</table>

<?php if (!empty($variables[$key + 1])): ?>
<h3>Local Variables</h3>

<table class="tracy-callstack-args">
<?php
foreach ($variables[$key + 1] as $k => $v) {
echo '<tr><th>$', Helpers::escapeHtml($k), '</th><td>';
echo $dump($v, $k);
echo "</td></tr>\n";
}
?>
</table>
<?php endif ?>


<?php elseif (!empty($row['args'])): ?>
<h3>Arguments</h3>

<table class="tracy-callstack-args tracy-callstack-args-warning">
<?php
try {
$r = isset($row['class']) ? new \ReflectionMethod($row['class'], $row['function']) : new \ReflectionFunction($row['function']);
Expand Down
2 changes: 2 additions & 0 deletions src/Tracy/BlueScreen/assets/section-stack-exception.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -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';
30 changes: 30 additions & 0 deletions src/Tracy/BlueScreen/assets/section-stack-variables.phtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace Tracy;

/**
* @var ?array $variables
*/

if (empty($variables[0])) {
return;
}
?>

<section class="tracy-section">
<h2 class="tracy-section-label"><a href="#" data-tracy-ref="^+" class="tracy-toggle tracy-collapsed">Local variables</a></h2>

<div class="tracy-section-panel tracy-collapsed">
<table class="tracy-callstack-args">
<?php
foreach ($variables[0] as $k => $v) {
echo '<tr><th>$', Helpers::escapeHtml($k), '</th><td>';
echo $dump($v, $k);
echo "</td></tr>\n";
}
?>
</table>
</div>
</section>
6 changes: 4 additions & 2 deletions src/Tracy/Dumper/Describer.php
Original file line number Diff line number Diff line change
Expand Up @@ -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']);
Expand All @@ -338,7 +341,6 @@ private static function findLocation(): ?array
$location = $item;
continue;
}
} catch (\ReflectionException) {
}
}

Expand Down

0 comments on commit 14e0d01

Please sign in to comment.