1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Merge branch 'PHP-8.4'

* PHP-8.4:
  Fix GH-14082: Segmentation fault on unknown address 0x600000000018 in ext/opcache/jit/zend_jit.c
This commit is contained in:
Niels Dossche
2025-06-23 22:29:00 +02:00
3 changed files with 79 additions and 0 deletions

View File

@@ -57,6 +57,8 @@
#ifdef HAVE_JIT
# include "jit/zend_jit.h"
# include "Optimizer/zend_func_info.h"
# include "Optimizer/zend_call_graph.h"
#endif
#ifndef ZEND_WIN32
@@ -4537,6 +4539,39 @@ static void preload_load(size_t orig_map_ptr_static_last)
}
}
#if HAVE_JIT
static void zend_accel_clear_call_graph_ptrs(zend_op_array *op_array)
{
ZEND_ASSERT(ZEND_USER_CODE(op_array->type));
zend_func_info *info = ZEND_FUNC_INFO(op_array);
if (info) {
info->caller_info = NULL;
info->callee_info = NULL;
}
}
static void accel_reset_arena_info(zend_persistent_script *script)
{
zend_op_array *op_array;
zend_class_entry *ce;
zend_accel_clear_call_graph_ptrs(&script->script.main_op_array);
ZEND_HASH_MAP_FOREACH_PTR(&script->script.function_table, op_array) {
zend_accel_clear_call_graph_ptrs(op_array);
} ZEND_HASH_FOREACH_END();
ZEND_HASH_MAP_FOREACH_PTR(&script->script.class_table, ce) {
ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) {
if (op_array->scope == ce
&& op_array->type == ZEND_USER_FUNCTION
&& !(op_array->fn_flags & ZEND_ACC_ABSTRACT)
&& !(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) {
zend_accel_clear_call_graph_ptrs(op_array);
}
} ZEND_HASH_FOREACH_END();
} ZEND_HASH_FOREACH_END();
}
#endif
static zend_result accel_preload(const char *config, bool in_child)
{
zend_file_handle file_handle;
@@ -4749,6 +4784,18 @@ static zend_result accel_preload(const char *config, bool in_child)
} ZEND_HASH_FOREACH_END();
ZCSG(saved_scripts)[i] = NULL;
#if HAVE_JIT
/* During persisting, the JIT may trigger and fill in the call graph.
* The call graph info is allocated on the arena which will be gone after preloading.
* To prevent invalid accesses during normal requests, the arena data should be cleared.
* This has to be done after all scripts have been persisted because shared op arrays between
* scripts can change the call graph. */
accel_reset_arena_info(ZCSG(preload_script));
for (zend_persistent_script **scripts = ZCSG(saved_scripts); *scripts; scripts++) {
accel_reset_arena_info(*scripts);
}
#endif
zend_shared_alloc_save_state();
accel_interned_strings_save_state();

View File

@@ -0,0 +1,23 @@
--TEST--
GH-14082 (Segmentation fault on unknown address 0x600000000018 in ext/opcache/jit/zend_jit.c)
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.jit=1235
opcache.jit_buffer_size=16M
opcache.preload={PWD}/preload_gh14082.inc
--EXTENSIONS--
opcache
--SKIPIF--
<?php
if (PHP_OS_FAMILY == 'Windows') die('skip Preloading is not supported on Windows');
?>
--FILE--
<?php
Foo::test();
echo "ok\n";
?>
--EXPECT--
int(1)
int(1)
ok

View File

@@ -0,0 +1,9 @@
<?php
class Foo {
public static function test() {
static $i = 0;
var_dump(++$i);
}
}
Foo::test();