Bug #77615 [Asn]: Undefined class constant 'self::DOES_EXIST'
Edit report at https://bugs.php.net/bug.php?id=77615&edit=1
ID: 77615
Updated by: nikic@php.net
Reported by: mberchtold at gmail dot com
Summary: Undefined class constant 'self::DOES_EXIST'
Status: Assigned
Type: Bug
Package: opcache
Operating System: Windows 10 x64
PHP Version: 7.4
Assigned To: dmitry
Block user comment: N
Private report: N
New Comment:
I've fixed the exception issue in https://github.com/php/php-src/commit/ade9d5e95b879def3ce5b2b0c117ce1258c211ee.
However, there is still some issue for the following case (run under valgrind):
trait T {
public function test() {
return 123;
}
}
class A {
const C = UNDEF;
use T;
}
I believe the problem is that T::test() is shared with A, but one of the classes is preloaded while
the other isn't. Depending on where we encounter it first, we might treat it as immutable or
not. But not sure what exactly is happening here.
Previous Comments:
------------------------------------------------------------------------
[2019-02-15 09:56:36] nikic@php.net
@dmitry: I believe the properties_info_table issue should be fixed with https://github.com/php/php-src/commit/ffc7e953ea908f05703d573faadc51707936321c.
However, this doesn't resolve the original issue. Something like
class Foo {
const A = self::DOES_NOT_EXIST;
}
is enough to reproduce a crash. When we call zend_update_constant_ex it may throw an Error, but this
of course doesn't work during preloading.
------------------------------------------------------------------------
[2019-02-14 14:54:24] dmitry@php.net
This is not a Widows related problem.
The problem introduces by "typed properties" that allocate
"ce->properties_info_table" at ARENA.
See https://github.com/php/php-src/blob/master/ext/opcache/zend_persist_calc.c#L391
Then assert traps, because we can't keep direct pointer from shared to process memory.
Nikita, can you please take a look.
------------------------------------------------------------------------
[2019-02-14 14:45:48] dmitry@php.net
"Typed properties" conflict with "preloading" (even if they are not used).
------------------------------------------------------------------------
[2019-02-13 19:56:55] mberchtold at gmail dot com
This is the preload.php script I'm using:
<?php
function _preload($preload, string $pattern = "/\.php$/", array $ignore = []) {
if (is_array($preload)) {
foreach ($preload as $path) {
_preload($path, $pattern, $ignore);
}
} else if (is_string($preload)) {
$path = $preload;
if (!in_array($path, $ignore)) {
if (is_dir($path)) {
if ($dh = opendir($path)) {
while (($file = readdir($dh)) !== false) {
if ($file !== "." && $file !== "..") {
_preload($path . DIRECTORY_SEPARATOR . $file, $pattern, $ignore);
}
}
closedir($dh);
}
} else if (is_file($path) && preg_match($pattern, $path)) {
// HACK: skip classes with possible reserved names
// PHP Fatal error: Cannot use 'Float' as class name as it is reserved in
\vendor\zendframework\zend-db\src\Sql\Ddl\Column\Float.php on line 22
$basename = basename($path);
if ($basename != 'Float.php'
&& $basename != 'Int.php'
&& $basename != 'Null.php'
&& $basename != 'Object.php'
)
{
if (!opcache_compile_file($path)) {
trigger_error("Preloading Failed", E_USER_ERROR);
}
}
}
}
}
}
_preload(['C:\vendor\zendframework\zend-validator\src']);
------------------------------------------------------------------------
[2019-02-13 19:54:33] mberchtold at gmail dot com
To reproduce it, it is sufficient to preload the zend-validator\src folder from ZF3:
_preload(['C:\vendor\zendframework\zend-validator\src']);
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=77615
--
Edit this bug report at https://bugs.php.net/bug.php?id=77615&edit=1
Thread (8 messages)