From 28b6c6e7260c9ad552bb52a9ece1eede48b8a27f Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Wed, 20 May 2026 13:05:15 +0800 Subject: [PATCH] =?UTF-8?q?feat(debug):=20=E6=B7=BB=E5=8A=A0=E8=B0=83?= =?UTF-8?q?=E8=AF=95=E4=BF=A1=E6=81=AF=E6=94=AF=E6=8C=81=E4=BB=A5=E6=94=B9?= =?UTF-8?q?=E8=BF=9B=E5=BC=82=E5=B8=B8=E5=9B=9E=E6=BA=AF=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 实现函数级别的调试信息生成,包括类方法和全局函数 - 添加命名空间前缀到调试函数名称中 - 集成 php::pushDebugFrame 和 php::popDebugFrame 用于运行时调试栈管理 - 添加调试信息启用和禁用机制 - 为嵌套函数调用添加异常传播测试用例 - 创建调试跟踪示例文件以验证功能实现 --- examples/debug_trace.php | 25 +++++++++++++++++++++++++ src/Php/CompilerBase.php | 17 +++++++++++++++-- tests/aot/debug_exception.phpt | 22 ++++++++++++++++++++++ 3 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 examples/debug_trace.php create mode 100644 tests/aot/debug_exception.phpt diff --git a/examples/debug_trace.php b/examples/debug_trace.php new file mode 100644 index 00000000..b21ecce0 --- /dev/null +++ b/examples/debug_trace.php @@ -0,0 +1,25 @@ +run(); +} \ No newline at end of file diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index e07e9d53..fad1a54b 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -1095,7 +1095,16 @@ class CompilerBase extends \PhpAot\Core\Translator $code .= $this->genPropertyPromotion($argInfo); } $this->indentLevel--; - $code .= $this->genDebugInfo(); + // 构建 PHP 级别的函数名用于 debug backtrace + if ($this->class) { + $debugName = $this->class . '::' . $this->function; + } else { + $debugName = $this->function; + if ($this->namespace) { + $debugName = $this->namespace . '\\' . $debugName; + } + } + $code .= $this->genDebugInfo(null, $debugName, $v->getStartLine()); // 函数中存在动态调用的函数,需要在运行时动态切换作用域 if ($this->methodDef and $this->methodDef->hasDynamicCall) { @@ -5541,12 +5550,16 @@ class CompilerBase extends \PhpAot\Core\Translator return 'this_.call(' . $this->getMethodPtr($parentClass, $method) . ', ' . $this->parseCallArgs($expr->args) . ')'; } - protected function genDebugInfo(?NodeAbstract $stmt = null): string + protected function genDebugInfo(?NodeAbstract $stmt = null, string $functionName = '', int $startLine = 0): string { $code = ''; if ($this->debug) { if ($stmt) { $code .= 'php::traceDebugInfo("' . $this->escapeString($this->file) . '", ' . $stmt->getLine() . ');' . PHP_EOL; + } elseif ($functionName) { + $code .= 'php::enableDebugInfo();' . PHP_EOL; + $code .= 'php::pushDebugFrame("' . $this->escapeString($this->file) . '", ' . $startLine . ', "' . $this->escapeString($functionName) . '");' . PHP_EOL; + $code .= 'ON_SCOPE_EXIT(php::popDebugFrame());' . PHP_EOL; } else { $code .= 'php::enableDebugInfo();' . PHP_EOL; } diff --git a/tests/aot/debug_exception.phpt b/tests/aot/debug_exception.phpt new file mode 100644 index 00000000..b9f20fb6 --- /dev/null +++ b/tests/aot/debug_exception.phpt @@ -0,0 +1,22 @@ +--TEST-- +debug exception propagation through nested function calls +--FILE-- +getMessage() . "\n"; + echo "Exception class: " . get_class($e) . "\n"; + } +} +?> +--EXPECT-- +Caught: error at inner level +Exception class: Exception