Include line numbers in all of OPcache's debug dumps of bytecode

未关闭
#25,337 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

这个 Issue 还没有评估数据。

描述

Extension: opcache Feature Status: Needs Triage

Description

opcache.opt_debug_level lets the CLI SAPI dump the bytecode of a file without executing it, for instance:

php -d opcache.enable_cli=1 -d opcache.opt_debug_level=0x10000 -r 'opcache_compile_file("file.php");'

For tools that need to know which source lines carry opcodes, the line number of each opline is essential. Code coverage is an example: whether a line is executable depends on decisions the compiler makes (whether a match expression is compiled to a jump table, whether constants are substituted, ...), see sebastianbergmann/php-code-coverage#1380. Compiling a file with opcache_compile_file() and reading the line numbers from the dump would answer that question for the bytecode that actually runs, without executing the file and without re-implementing the compiler's decisions.

Current state

zend_dump_op_array() supports ZEND_DUMP_LINE_NUMBERS, which prefixes each opline with Lnnnn (phpdbg's -p uses it). The dumps that OPcache emits for opcache.opt_debug_level pass hard-coded flags to it:

  • PHP 8.4 and PHP 8.5: no dump includes line numbers, and there is no way to request them.
  • PHP 8.6: the fix for GH-18985 (07d308a0deb) introduced ZEND_DUMP_LINE_NUMBERS_PASSTHRU (bit 30, 0x40000000). It adds line numbers to the "before optimizer" dump (opcache.opt_debug_level=0x40010000), but not to any other dump.

With this file (hooks.php, any file works):

<?php declare(strict_types=1);
final class Temperature
{
    public float $celsius = 0.0 {
        set {
            if ($value < -273.15) {
                throw new ValueError('Below absolute zero');
            }

            $this->celsius = $value;
        }
    }
}

opcache.opt_debug_level=0x40010000 (before optimizer) on PHP 8.6.1-dev:

Temperature::$celsius::set:
L0004 0000 CV0($value) = RECV 1
L0006 0001 T1 = IS_SMALLER CV0($value) float(-273.15)
L0006 0002 JMPZ T1 0007
L0007 0003 T2 = NEW 1 string("ValueError")
...

opcache.opt_debug_level=0x40020000 (after optimizer) on PHP 8.6.1-dev:

Temperature::$celsius::set:
0000 CV0($value) = RECV 1
0001 T1 = IS_SMALLER CV0($value) float(-273.15)
0002 JMPZ T1 0007
0003 T1 = NEW 1 string("ValueError")
...
Request
  1. Honor ZEND_DUMP_LINE_NUMBERS_PASSTHRU in all dumps that opcache.opt_debug_level controls, not only in the "before optimizer" dump: at least the "after optimizer" dumps (in zend_optimize() and the one emitted after the call graph pass in zend_optimize_script()), and ideally also the "after pass N", block pass, and DFA dumps. When the optimizer is enabled, the optimized bytecode is what runs and what extensions such as Xdebug and PCOV observe, so the "after optimizer" dump is the one that tells which lines carry opcodes at run time. One way to implement this would be to derive the additional dump flags once from ctx->debug_level and pass them to every zend_dump_op_array() call of the optimizer.
  2. Document the bit together with the other values of opcache.opt_debug_level. I could not find it in php.ini-development, UPGRADING, or NEWS (which only mentions the fix for GH-18985).
主要语言
C
星标
41.8k
派生
8.5k
平均合并
2 天 12 小时
30 天内合并 PR
137

环境准备

  • 没有 Dockerfile 或 Docker Compose 文件
  • 没有 Pull Request 模板
  • 阅读贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

php/php-src 的其他 Issue

查看 php/php-src 的全部 Issue

相似的 Issue

更多 C Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。