Skip to content

PHP crashes in _zend_observe_fcall_begin() on internal method inherited by user child when run with opcache #9871

@dstogov

Description

@dstogov

Description

The following code crashes when run with observer and opcache enabled (php -d opcache.enable=1 -d opcache.jit=0 -d zend_test.observer.enabled=1 -d zend_test.observer.observe_all=1 -d zend_test.observer.show_return_value=1 bug.php)

<?php
class MyReflectionProperty extends ReflectionProperty {
}

class A {
    protected $protected = 'a';
}

$property = new MyReflectionProperty('A', 'protected');
$property->setAccessible(true);
?>

Resulted in this output:

SIGSEGV
    #0 0x2502451 in _zend_observe_fcall_begin php8.2/Zend/zend_observer.c:227
    #1 0x2502858 in zend_observer_fcall_begin php8.2/Zend/zend_observer.c:257
    #2 0x2140129 in ZEND_DO_FCALL_SPEC_OBSERVER_HANDLER php8.2/Zend/zend_vm_execute.h:2058
    #3 0x23c4531 in execute_ex php8.2/Zend/zend_vm_execute.h:56056
    #4 0x23dfb1a in zend_execute php8.2/Zend/zend_vm_execute.h:60380

But I expected this output instead:

<!-- init '%sbug.php' -->
<file '%sbug.php'>
  <!-- init ReflectionProperty::__construct() -->
  <ReflectionProperty::__construct>
  </ReflectionProperty::__construct:NULL>
  <!-- init ReflectionProperty::setAccessible() -->
  <ReflectionProperty::setAccessible>
  </ReflectionProperty::setAccessible:NULL>
</file '%sbug.php'>

The crash occurs because the recent engine changes related to observation of internal functions don't respect opcache.
Internal method inherited from internal class is stored in opcache SHM and corresponding map_ptr slot for run_time_cache is allocated. However, run_time_cache itself is not allocated. It should be allocated on each request.

PHP Version

PHP 8.2.0-dev

Operating System

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions