From a2a0670f5db77d2c378d4d207ecfe6e053b85bcf Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Wed, 15 Dec 2021 00:17:11 +0100 Subject: [PATCH 1/2] Fix #81679: Tracing JIT crashes on reattaching When a new process reattaches to OPcache, tracing JIT causes segfaults, because each new process allocates its own `zend_jit_traces` and `zend_jit_exit_groups` in SHM, although these need to be shared between all processes. We solve that by only allocating these structs for the first process, and store the pointers in `accel_shared_globals`, so we can reassign them when a new process reattaches. --- ext/opcache/ZendAccelerator.h | 3 +++ ext/opcache/jit/zend_jit.c | 2 +- ext/opcache/jit/zend_jit_trace.c | 37 +++++++++++++++++++++----------- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h index b9e3f2a81de8..826f1247f081 100644 --- a/ext/opcache/ZendAccelerator.h +++ b/ext/opcache/ZendAccelerator.h @@ -287,6 +287,9 @@ typedef struct _zend_accel_shared_globals { /* Interned Strings Support (must be the last element) */ zend_string_table interned_strings; + + void *jit_traces; + const void **jit_exit_groups; } zend_accel_shared_globals; #ifdef ZEND_WIN32 diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index bbe879b9fddd..fdffcbc1034c 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -4390,7 +4390,7 @@ ZEND_EXT_API int zend_jit_startup(void *buf, size_t size, zend_bool reattached) #endif } - if (zend_jit_trace_startup() != SUCCESS) { + if (zend_jit_trace_startup(reattached) != SUCCESS) { return FAILURE; } diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index fa29a0399774..dd37f33ad685 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -48,20 +48,33 @@ static zend_always_inline const char *zend_jit_trace_star_desc(uint8_t trace_fla } } -static int zend_jit_trace_startup(void) +static int zend_jit_trace_startup(zend_bool reattached) { - zend_jit_traces = (zend_jit_trace_info*)zend_shared_alloc(sizeof(zend_jit_trace_info) * JIT_G(max_root_traces)); - if (!zend_jit_traces) { - return FAILURE; - } - zend_jit_exit_groups = (const void**)zend_shared_alloc(sizeof(void*) * (ZEND_JIT_TRACE_MAX_EXITS/ZEND_JIT_EXIT_POINTS_PER_GROUP)); - if (!zend_jit_exit_groups) { - return FAILURE; + if (!reattached) { + zend_jit_traces = (zend_jit_trace_info*)zend_shared_alloc(sizeof(zend_jit_trace_info) * JIT_G(max_root_traces)); + if (!zend_jit_traces) { + return FAILURE; + } + zend_jit_exit_groups = (const void**)zend_shared_alloc(sizeof(void*) * (ZEND_JIT_TRACE_MAX_EXITS/ZEND_JIT_EXIT_POINTS_PER_GROUP)); + if (!zend_jit_exit_groups) { + return FAILURE; + } + ZEND_JIT_TRACE_NUM = 1; + ZEND_JIT_COUNTER_NUM = 0; + ZEND_JIT_EXIT_NUM = 0; + ZEND_JIT_EXIT_COUNTERS = 0; + ZCSG(jit_traces) = zend_jit_traces; + ZCSG(jit_exit_groups) = zend_jit_exit_groups; + } else { + zend_jit_traces = ZCSG(jit_traces); + if (!zend_jit_traces) { + return FAILURE; + } + zend_jit_exit_groups = ZCSG(jit_exit_groups); + if (!zend_jit_exit_groups) { + return FAILURE; + } } - ZEND_JIT_TRACE_NUM = 1; - ZEND_JIT_COUNTER_NUM = 0; - ZEND_JIT_EXIT_NUM = 0; - ZEND_JIT_EXIT_COUNTERS = 0; memset(&dummy_op_array, 0, sizeof(dummy_op_array)); dummy_op_array.fn_flags = ZEND_ACC_DONE_PASS_TWO; From 87261611b2f80811a9cfa3e36e3bad43d41dc988 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Wed, 15 Dec 2021 11:47:44 +0100 Subject: [PATCH 2/2] interned_strings must be last element of zend_accel_shared_globals --- ext/opcache/ZendAccelerator.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h index 826f1247f081..610decd7995d 100644 --- a/ext/opcache/ZendAccelerator.h +++ b/ext/opcache/ZendAccelerator.h @@ -285,11 +285,12 @@ typedef struct _zend_accel_shared_globals { /* uninitialized HashTable Support */ uint32_t uninitialized_bucket[-HT_MIN_MASK]; - /* Interned Strings Support (must be the last element) */ - zend_string_table interned_strings; - + /* Tracing JIT */ void *jit_traces; const void **jit_exit_groups; + + /* Interned Strings Support (must be the last element) */ + zend_string_table interned_strings; } zend_accel_shared_globals; #ifdef ZEND_WIN32