mirror of
https://github.com/php/php-src.git
synced 2024-11-23 18:04:36 +08:00
ext/opcache/jit: handle zend_jit_find_trace() failures
Commit 6c25413
added the flag ZEND_JIT_EXIT_INVALIDATE which resets
the trace handlers in zend_jit_trace_exit(), but forgot to consider
that on ZEND_JIT_TRACE_STOP_LINK, this changed handler gets passed to
zend_jit_find_trace(), causing it to fail, either by returning 0
(results in bogus data) or by aborting due to ZEND_UNREACHABLE(). In
either case, this crashes the PHP process.
I'm not quite sure how to fix this multi-threading problem properly;
my suggestion is to just fail the zend_jit_trace() call. After all,
the whole ZEND_JIT_EXIT_INVALIDATE fix was about reloading modified
scripts, so there's probably no point in this pending zend_jit_trace()
call.
This commit is contained in:
parent
a3891d9d1a
commit
b26b758952
1
NEWS
1
NEWS
@ -24,6 +24,7 @@ PHP NEWS
|
||||
- Opcache:
|
||||
. Fix inverted bailout value in zend_runtime_jit() (Max Kellermann).
|
||||
. Fix access to uninitialized variable in accel_preload(). (nielsdos)
|
||||
. Fix zend_jit_find_trace() crashes. (Max Kellermann)
|
||||
|
||||
- PHPDBG:
|
||||
. Fix undefined behaviour in phpdbg_load_module_or_extension(). (nielsdos)
|
||||
|
@ -247,6 +247,13 @@ static void zend_jit_trace_add_code(const void *start, uint32_t size)
|
||||
t->code_size = size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Locate a trace in the #zend_jit_traces array with the specified
|
||||
* #code_start address.
|
||||
*
|
||||
* @return the #zend_jit_traces index or 0 if no such #code_start
|
||||
* address was found
|
||||
*/
|
||||
static uint32_t zend_jit_find_trace(const void *addr)
|
||||
{
|
||||
uint32_t i;
|
||||
@ -256,7 +263,6 @@ static uint32_t zend_jit_find_trace(const void *addr)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
ZEND_UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -6843,6 +6849,15 @@ done:
|
||||
const void *timeout_exit_addr = NULL;
|
||||
|
||||
t->link = zend_jit_find_trace(p->opline->handler);
|
||||
if (t->link == 0) {
|
||||
/* this can happen if ZEND_JIT_EXIT_INVALIDATE was handled
|
||||
* by zend_jit_trace_exit() in another thread after this
|
||||
* thread set ZEND_JIT_TRACE_STOP_LINK in zend_jit_trace_execute();
|
||||
* ZEND_JIT_EXIT_INVALIDATE resets the opline handler to one of
|
||||
* the "_counter_handler" functions, and these are not registered
|
||||
* tracer functions */
|
||||
goto jit_failure;
|
||||
}
|
||||
if ((zend_jit_traces[t->link].flags & ZEND_JIT_TRACE_USES_INITIAL_IP)
|
||||
&& !zend_jit_set_ip(&dasm_state, p->opline)) {
|
||||
goto jit_failure;
|
||||
|
Loading…
Reference in New Issue
Block a user