Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assertion failure Zend/zend_vm_execute.h JIT #18262

Open
YuanchengJiang opened this issue Apr 6, 2025 · 2 comments · May be fixed by #18297
Open

Assertion failure Zend/zend_vm_execute.h JIT #18262

YuanchengJiang opened this issue Apr 6, 2025 · 2 comments · May be fixed by #18297

Comments

@YuanchengJiang
Copy link

Description

The following code:

<?php
class B {
public int $fusion;
}
class C extends B {
}
class D extends C {
public function __destruct() {
}
}
$tests = [
[C::class, new C()],
[C::class, new B()],
[D::class, new B()],
];
foreach ($tests as [$class, $instance]) {
$obj = (new ReflectionClass($class))->newLazyProxy(function ($obj) use ($instance) {
$instance->b = 1;
return $instance;
});
var_dump($obj->b);
}

Resulted in this output:

php: Zend/zend_vm_execute.h:18745: int ZEND_SEND_VAL_SPEC_TMPVAR_UNUSED_HANDLER(zend_execute_data *): Assertion `!(((zend_executor_globals *) (((char*) _tsrm_ls_cache)+(executor_globals_offset)))->exception)' failed.
Aborted (core dumped)

To reproduce:

./php-src/sapi/cli/php  -d "opcache.jit_hot_func=1" -d "opcache.jit_hot_side_exit=1" -d "zend_extension=/home/phpfuzz/WorkSpace/flowfusion/php-src/modules/opcache.so" -d "opcache.enable_cli=1" -d "opcache.jit=1254" ./test.php

Commit:

ac9392b855cc4db6792a8379223e1fd1bbebd157

Configurations:

CC="clang-12" CXX="clang++-12" CFLAGS="-DZEND_VERIFY_TYPE_INFERENCE" CXXFLAGS="-DZEND_VERIFY_TYPE_INFERENCE" ./configure --enable-debug --enable-address-sanitizer --enable-undefined-sanitizer --enable-re2c-cgoto --enable-fpm --enable-litespeed --enable-phpdbg-debug --enable-zts --enable-bcmath --enable-calendar --enable-dba --enable-dl-test --enable-exif --enable-ftp --enable-gd --enable-gd-jis-conv --enable-mbstring --enable-pcntl --enable-shmop --enable-soap --enable-sockets --enable-sysvmsg --enable-zend-test --with-zlib --with-bz2 --with-curl --with-enchant --with-gettext --with-gmp --with-mhash --with-ldap --with-libedit --with-readline --with-snmp --with-sodium --with-xsl --with-zip --with-mysqli --with-pdo-mysql --with-pdo-pgsql --with-pgsql --with-sqlite3 --with-pdo-sqlite --with-webp --with-jpeg --with-freetype --enable-sigchild --with-readline --with-pcre-jit --with-iconv

Operating System:

Ubuntu 20.04 Host, Docker 0599jiangyc/flowfusion:latest

This report is automatically generated by FlowFusion

PHP Version

ac9392b

Operating System

No response

@Girgias
Copy link
Member

Girgias commented Apr 6, 2025

@arnaud-lb this seems to be related to lazy objects, could you have a look?

@arnaud-lb
Copy link
Member

Simplified reproducer (without lazy objects) :

class B {
    public function __construct($init) {
        if ($init) {
            $this->b = $init;
        }
    }
}

$tests = [
    new B(1),
    new B(0),
];

set_error_handler(function () {
    throw new \Exception();
});

foreach ($tests as $obj) {
    var_dump($obj->b);
}

On the first iteration, $obj->b evaluates to int(1), but on the second one an exception is thrown.

The loop is JIT'ed and a type guard is emitted after fetching $obj->b (here). When the guard fails we side-exit before checking EG(exception) (here), so the assertion ZEND_ASSERT(!EG(exception)) fails in ZEND_SEND_VAL_SPEC_TMPVAR_UNUSED_HANDLER:

---- TRACE 1 start (loop) $main() test2.php:20
int(1)
0014 FE_FETCH_R V2 CV1($obj) 0020 ; op1(packed array) op2(undef)
0015 INIT_FCALL 1 96 string("var_dump")
     >init var_dump
0016 T3 = FETCH_OBJ_R CV1($obj) string("b") ; op1(object of class B)
0017 SEND_VAL T3 1 ; op1(int)
0018 DO_ICALL
     >call var_dump
0019 JMP 0014
---- TRACE 1 stop (loop)
---- TRACE 1 exit info
     exit_5: 0017/0009/4/CALL X2:array X3:unknown(zval_copy(rax))
---- TRACE 1 compiled

[...]

     TRACE 1 exit 5 $main() test2.php:21
---- TRACE 2 start (side trace 1/5) $main() test2.php:21
php: Zend/zend_vm_execute.h:18744: ZEND_SEND_VAL_SPEC_TMPVAR_UNUSED_HANDLER: Assertion `!(executor_globals.exception)' failed.
Aborted (core dumped)

@arnaud-lb arnaud-lb linked a pull request Apr 10, 2025 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants