From cb338635c2dac27acc5d42794a31e83a4bca24c2 Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Mon, 18 May 2020 08:54:21 +0200 Subject: [PATCH 01/11] Don't use Zend signal handling to protect shared memory in ZendAccelerator.c Zend signal handling was added in PHP 5.4 to protect against signal handlers running at inopportune times and causing bugs. The details are in this RFC: https://wiki.php.net/rfc/zendsignals In short, the handlers for 7 signals of concern are saved and replaced with a generic handler which delegates to the specific handlers. Inside 'critical sections', however, the generic handler puts all information regarding a signal on a queue and just returns. At the end of the critical section, all pending signals on the queue are processed and the specific handlers are called. However, in PHP 7.1, the `vm_interrupt` flag was added which also protects against script execution timeouts, etc. occurring at wrong times. This eliminated most of the use cases of Zend signal handling. The one which has remained until now is accessing shared memory in OPCache. If that can be eliminated, there will be no need for Zend signal handling any more and a subsystem can be unceremoniously ripped out. The funny thing about the whole idea of Zend signal handling is... it seems to duplicate what Unix kernels already do. Each process/thread in Unix already has a signal mask which can be used to block signals from being delivered at inopportune times. If a signal arrives when it is masked, the kernel will store it and only deliver it once it is unmasked. So rather than going through the whole dance of storing signals on a queue and unqueueing them later... let the kernel do its job. --- ext/opcache/ZendAccelerator.c | 106 +++++++++++++++++++++++++--------- 1 file changed, 78 insertions(+), 28 deletions(-) diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 25c76c4a5e4a..506971e3b668 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -118,6 +118,49 @@ zend_bool file_cache_only = 0; /* process uses file cache only */ zend_bool fallback_process = 0; /* process uses file cache fallback */ #endif +#ifdef HAVE_SIGPROCMASK +static sigset_t mask_all_signals; + +# if ZEND_DEBUG +# ifdef ZTS + ZEND_TLS int _signals_masked = 0; +# else + static int _signals_masked = 0; +# endif +# define DEBUG_BLOCK_ALL_SIGNALS() _signals_masked += 1 +# define DEBUG_UNBLOCK_ALL_SIGNALS() \ + if (--_signals_masked) \ + zend_error_noreturn(E_ERROR, "Cannot nest BLOCK_ALL_SIGNALS; it is not re-entrant") +# else +# define DEBUG_BLOCK_ALL_SIGNALS() do {} while (0) +# define DEBUG_UNBLOCK_ALL_SIGNALS() do {} while (0) +# endif + +# define BLOCK_ALL_SIGNALS() \ + sigset_t _oldmask; \ + DEBUG_BLOCK_ALL_SIGNALS(); \ + MASK_ALL_SIGNALS() +# define UNBLOCK_ALL_SIGNALS() \ + DEBUG_UNBLOCK_ALL_SIGNALS(); \ + UNMASK_ALL_SIGNALS() + +# ifdef ZTS +# define MASK_ALL_SIGNALS() \ + tsrm_sigmask(SIG_BLOCK, &mask_all_signals, &_oldmask) +# define UNMASK_ALL_SIGNALS() \ + tsrm_sigmask(SIG_SETMASK, &_oldmask, NULL) +# else +# define MASK_ALL_SIGNALS() \ + sigprocmask(SIG_BLOCK, &mask_all_signals, &_oldmask) +# define UNMASK_ALL_SIGNALS() \ + sigprocmask(SIG_SETMASK, &_oldmask, NULL) +# endif + +#else +# define BLOCK_ALL_SIGNALS() do {} while(0) +# define UNBLOCK_ALL_SIGNALS() do {} while(0) +#endif + static zend_op_array *(*accelerator_orig_compile_file)(zend_file_handle *file_handle, int type); static int (*accelerator_orig_zend_stream_open_function)(const char *filename, zend_file_handle *handle ); static zend_string *(*accelerator_orig_zend_resolve_path)(const char *filename, size_t filename_len); @@ -745,7 +788,7 @@ static zend_string* ZEND_FASTCALL accel_replace_string_by_shm_permanent(zend_str static void accel_use_shm_interned_strings(void) { - HANDLE_BLOCK_INTERRUPTIONS(); + BLOCK_ALL_SIGNALS(); SHM_UNPROTECT(); zend_shared_alloc_lock(); @@ -760,7 +803,7 @@ static void accel_use_shm_interned_strings(void) zend_shared_alloc_unlock(); SHM_PROTECT(); - HANDLE_UNBLOCK_INTERRUPTIONS(); + UNBLOCK_ALL_SIGNALS(); } #ifndef ZEND_WIN32 @@ -1159,7 +1202,7 @@ char *accel_make_persistent_key(const char *path, size_t path_length, int *key_l zend_string *str = accel_find_interned_string(cwd_str); if (!str) { - HANDLE_BLOCK_INTERRUPTIONS(); + BLOCK_ALL_SIGNALS(); SHM_UNPROTECT(); zend_shared_alloc_lock(); str = accel_new_interned_string(zend_string_copy(cwd_str)); @@ -1169,7 +1212,7 @@ char *accel_make_persistent_key(const char *path, size_t path_length, int *key_l } zend_shared_alloc_unlock(); SHM_PROTECT(); - HANDLE_UNBLOCK_INTERRUPTIONS(); + UNBLOCK_ALL_SIGNALS(); } if (str) { char buf[32]; @@ -1203,7 +1246,7 @@ char *accel_make_persistent_key(const char *path, size_t path_length, int *key_l zend_string *str = accel_find_interned_string(ZCG(include_path)); if (!str) { - HANDLE_BLOCK_INTERRUPTIONS(); + BLOCK_ALL_SIGNALS(); SHM_UNPROTECT(); zend_shared_alloc_lock(); str = accel_new_interned_string(zend_string_copy(ZCG(include_path))); @@ -1212,7 +1255,7 @@ char *accel_make_persistent_key(const char *path, size_t path_length, int *key_l } zend_shared_alloc_unlock(); SHM_PROTECT(); - HANDLE_UNBLOCK_INTERRUPTIONS(); + UNBLOCK_ALL_SIGNALS(); } if (str) { char buf[32]; @@ -1309,7 +1352,7 @@ int zend_accel_invalidate(const char *filename, size_t filename_len, zend_bool f if (force || !ZCG(accel_directives).validate_timestamps || do_validate_timestamps(persistent_script, &file_handle) == FAILURE) { - HANDLE_BLOCK_INTERRUPTIONS(); + BLOCK_ALL_SIGNALS(); SHM_UNPROTECT(); zend_shared_alloc_lock(); if (!persistent_script->corrupted) { @@ -1324,7 +1367,7 @@ int zend_accel_invalidate(const char *filename, size_t filename_len, zend_bool f } zend_shared_alloc_unlock(); SHM_PROTECT(); - HANDLE_UNBLOCK_INTERRUPTIONS(); + UNBLOCK_ALL_SIGNALS(); } } @@ -1905,11 +1948,11 @@ zend_op_array *file_cache_compile_file(zend_file_handle *file_handle, int type) } } - HANDLE_BLOCK_INTERRUPTIONS(); + BLOCK_ALL_SIGNALS(); SHM_UNPROTECT(); persistent_script = zend_file_cache_script_load(file_handle); SHM_PROTECT(); - HANDLE_UNBLOCK_INTERRUPTIONS(); + UNBLOCK_ALL_SIGNALS(); if (persistent_script) { /* see bug #15471 (old BTS) */ if (persistent_script->script.filename) { @@ -2068,13 +2111,13 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) persistent_script = (zend_persistent_script *)bucket->data; if (key && !persistent_script->corrupted) { - HANDLE_BLOCK_INTERRUPTIONS(); + BLOCK_ALL_SIGNALS(); SHM_UNPROTECT(); zend_shared_alloc_lock(); zend_accel_add_key(key, key_length, bucket); zend_shared_alloc_unlock(); SHM_PROTECT(); - HANDLE_UNBLOCK_INTERRUPTIONS(); + UNBLOCK_ALL_SIGNALS(); } } } @@ -2119,7 +2162,7 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) return NULL; } - HANDLE_BLOCK_INTERRUPTIONS(); + BLOCK_ALL_SIGNALS(); SHM_UNPROTECT(); /* If script is found then validate_timestamps if option is enabled */ @@ -2182,7 +2225,7 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) /* No memory left. Behave like without the Accelerator */ if (ZSMMG(memory_exhausted) || ZCSG(restart_pending)) { SHM_PROTECT(); - HANDLE_UNBLOCK_INTERRUPTIONS(); + UNBLOCK_ALL_SIGNALS(); if (ZCG(accel_directives).file_cache) { return file_cache_compile_file(file_handle, type); } @@ -2190,9 +2233,9 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) } SHM_PROTECT(); - HANDLE_UNBLOCK_INTERRUPTIONS(); + UNBLOCK_ALL_SIGNALS(); persistent_script = opcache_compile_file(file_handle, type, key, &op_array); - HANDLE_BLOCK_INTERRUPTIONS(); + BLOCK_ALL_SIGNALS(); SHM_UNPROTECT(); /* Try and cache the script and assume that it is returned from_shared_memory. @@ -2208,7 +2251,7 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) */ if (!persistent_script) { SHM_PROTECT(); - HANDLE_UNBLOCK_INTERRUPTIONS(); + UNBLOCK_ALL_SIGNALS(); return op_array; } if (from_shared_memory) { @@ -2263,7 +2306,7 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) persistent_script->dynamic_members.last_used = ZCG(request_time); SHM_PROTECT(); - HANDLE_UNBLOCK_INTERRUPTIONS(); + UNBLOCK_ALL_SIGNALS(); /* Fetch jit auto globals used in the script before execution */ if (persistent_script->ping_auto_globals_mask) { @@ -2369,13 +2412,13 @@ static zend_string* persistent_zend_resolve_path(const char *filename, size_t fi if (!persistent_script->corrupted) { if (key) { /* add another "key" for the same bucket */ - HANDLE_BLOCK_INTERRUPTIONS(); + BLOCK_ALL_SIGNALS(); SHM_UNPROTECT(); zend_shared_alloc_lock(); zend_accel_add_key(key, key_length, bucket); zend_shared_alloc_unlock(); SHM_PROTECT(); - HANDLE_UNBLOCK_INTERRUPTIONS(); + UNBLOCK_ALL_SIGNALS(); } else { ZCG(key_len) = 0; } @@ -2472,7 +2515,7 @@ int accel_activate(INIT_FUNC_ARGS) } #endif - HANDLE_BLOCK_INTERRUPTIONS(); + BLOCK_ALL_SIGNALS(); SHM_UNPROTECT(); if (ZCG(counted)) { @@ -2531,7 +2574,7 @@ int accel_activate(INIT_FUNC_ARGS) ZCG(accelerator_enabled) = ZCSG(accelerator_enabled); SHM_PROTECT(); - HANDLE_UNBLOCK_INTERRUPTIONS(); + UNBLOCK_ALL_SIGNALS(); if (ZCG(accelerator_enabled) && ZCSG(last_restart_time) != ZCG(last_restart_time)) { /* SHM was reinitialized. */ @@ -2958,6 +3001,10 @@ static int accel_startup(zend_extension *extension) } #endif +#ifdef HAVE_SIGPROCMASK + sigfillset(&mask_all_signals); +#endif + /* no supported SAPI found - disable acceleration and stop initialization */ if (accel_find_sapi() == FAILURE) { accel_startup_ok = 0; @@ -3230,7 +3277,7 @@ void zend_accel_schedule_restart(zend_accel_restart_reason reason) zend_accel_error(ACCEL_LOG_DEBUG, "Restart Scheduled! Reason: %s", zend_accel_restart_reason_text[reason]); - HANDLE_BLOCK_INTERRUPTIONS(); + BLOCK_ALL_SIGNALS(); SHM_UNPROTECT(); ZCSG(restart_pending) = 1; ZCSG(restart_reason) = reason; @@ -3243,7 +3290,7 @@ void zend_accel_schedule_restart(zend_accel_restart_reason reason) ZCSG(force_restart_time) = 0; } SHM_PROTECT(); - HANDLE_UNBLOCK_INTERRUPTIONS(); + UNBLOCK_ALL_SIGNALS(); } /* this is needed because on WIN32 lock is not decreased unless ZCG(counted) is set */ @@ -4461,6 +4508,9 @@ static int accel_preload(const char *config) char *orig_open_basedir; size_t orig_map_ptr_last; zval *zv; +#ifdef HAVE_SIGPROCMASK + sigset_t _oldmask; +#endif ZCG(enabled) = 0; ZCG(accelerator_enabled) = 0; @@ -4700,7 +4750,7 @@ static int accel_preload(const char *config) zend_shared_alloc_init_xlat_table(); - HANDLE_BLOCK_INTERRUPTIONS(); + MASK_ALL_SIGNALS(); SHM_UNPROTECT(); /* Store method names first, because they may be shared between preloaded and non-preloaded classes */ @@ -4719,7 +4769,7 @@ static int accel_preload(const char *config) ZCSG(preload_script) = preload_script_in_shared_memory(script); SHM_PROTECT(); - HANDLE_UNBLOCK_INTERRUPTIONS(); + UNMASK_ALL_SIGNALS(); zend_string_release(filename); @@ -4728,7 +4778,7 @@ static int accel_preload(const char *config) preload_load(); /* Store individual scripts with unlinked classes */ - HANDLE_BLOCK_INTERRUPTIONS(); + MASK_ALL_SIGNALS(); SHM_UNPROTECT(); i = 0; @@ -4745,7 +4795,7 @@ static int accel_preload(const char *config) accel_interned_strings_save_state(); SHM_PROTECT(); - HANDLE_UNBLOCK_INTERRUPTIONS(); + UNMASK_ALL_SIGNALS(); zend_shared_alloc_destroy_xlat_table(); From 650834716764bdc3cc44d0e7bbf8b6c431c0fa64 Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Mon, 18 May 2020 09:07:15 +0200 Subject: [PATCH 02/11] Remove unused Zend signal handling #defines from zend.h --- Zend/zend.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/Zend/zend.h b/Zend/zend.h index cd41cde5ef1b..33cd2eca0a41 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -42,9 +42,6 @@ #define zend_sprintf sprintf -#define HANDLE_BLOCK_INTERRUPTIONS() ZEND_SIGNAL_BLOCK_INTERRUPTIONS() -#define HANDLE_UNBLOCK_INTERRUPTIONS() ZEND_SIGNAL_UNBLOCK_INTERRUPTIONS() - #define INTERNAL_FUNCTION_PARAMETERS zend_execute_data *execute_data, zval *return_value #define INTERNAL_FUNCTION_PARAM_PASSTHRU execute_data, return_value From 582449ffc3342e555f25160d615d9d7d309390ee Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Mon, 18 May 2020 09:06:24 +0200 Subject: [PATCH 03/11] Don't use Zend signals for script execution timeouts --- Zend/zend_execute_API.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 6986841db259..148b502a8f1b 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1258,9 +1258,6 @@ static void zend_set_timeout_ex(zend_long seconds, int reset_signals) /* {{{ */ # endif if (reset_signals) { -# ifdef ZEND_SIGNALS - zend_signal(signo, zend_timeout_handler); -# else sigset_t sigset; # ifdef HAVE_SIGACTION struct sigaction act; @@ -1275,7 +1272,6 @@ static void zend_set_timeout_ex(zend_long seconds, int reset_signals) /* {{{ */ sigemptyset(&sigset); sigaddset(&sigset, signo); sigprocmask(SIG_UNBLOCK, &sigset, NULL); -# endif /* ZEND_SIGNALS */ } } #endif /* HAVE_SETITIMER */ From 035bd52a40b2bc73d3aada571a1d63bb8914dc0d Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Mon, 18 May 2020 09:38:08 +0200 Subject: [PATCH 04/11] Don't use Zend signal handling in pcntl The deferred signal delivery provided by Zend signal handling is not used anywhere now, so there is no need to go through `zend_sigaction` in pcntl. Since `zend_sigaction` did have the effect of unblocking the signal whose handler has been set, add that in pcntl to avoid changing behavior. The one thing which will change is that Zend signal handling ignored the signal mask provided by pcntl and used its own. Now the signal mask requested by pcntl will actually be used. --- ext/pcntl/pcntl.c | 4 ++-- ext/pcntl/php_signal.c | 29 ++++++++++++++++++----------- ext/pcntl/php_signal.h | 4 ++-- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c index 6f9fd8a18208..aceffe1c095e 100644 --- a/ext/pcntl/pcntl.c +++ b/ext/pcntl/pcntl.c @@ -936,7 +936,7 @@ PHP_FUNCTION(pcntl_signal) php_error_docref(NULL, E_WARNING, "Invalid value for handle argument specified"); RETURN_FALSE; } - if (php_signal(signo, (Sigfunc *) Z_LVAL_P(handle), (int) restart_syscalls) == (void *)SIG_ERR) { + if (php_signal(signo, (Sigfunc *) Z_LVAL_P(handle), (int) restart_syscalls) == FAILURE) { PCNTL_G(last_error) = errno; php_error_docref(NULL, E_WARNING, "Error assigning signal"); RETURN_FALSE; @@ -959,7 +959,7 @@ PHP_FUNCTION(pcntl_signal) handle = zend_hash_index_update(&PCNTL_G(php_signal_table), signo, handle); Z_TRY_ADDREF_P(handle); - if (php_signal4(signo, pcntl_signal_handler, (int) restart_syscalls, 1) == (void *)SIG_ERR) { + if (php_signal4(signo, pcntl_signal_handler, (int) restart_syscalls, 1) == FAILURE) { PCNTL_G(last_error) = errno; php_error_docref(NULL, E_WARNING, "Error assigning signal"); RETURN_FALSE; diff --git a/ext/pcntl/php_signal.c b/ext/pcntl/php_signal.c index 95b4a16d6df9..53d30fd42b74 100644 --- a/ext/pcntl/php_signal.c +++ b/ext/pcntl/php_signal.c @@ -17,13 +17,19 @@ #include "TSRM.h" #include "php_signal.h" #include "Zend/zend.h" -#include "Zend/zend_signal.h" + +#ifdef ZTS +# define php_sigprocmask(how, set, oldset) tsrm_sigmask((how), (set), (oldset)) +#else +# define php_sigprocmask(how, set, oldset) sigprocmask((how), (set), (oldset)) +#endif /* php_signal using sigaction is derived from Advanced Programming * in the Unix Environment by W. Richard Stevens p 298. */ -Sigfunc *php_signal4(int signo, Sigfunc *func, int restart, int mask_all) +int php_signal4(int signo, Sigfunc *func, int restart, int mask_all) { - struct sigaction act,oact; + struct sigaction act; + sigset_t sigset; #ifdef HAVE_STRUCT_SIGINFO_T act.sa_sigaction = func; @@ -48,18 +54,19 @@ Sigfunc *php_signal4(int signo, Sigfunc *func, int restart, int mask_all) act.sa_flags |= SA_RESTART; /* SVR4, 4.3+BSD */ #endif } - if (zend_sigaction(signo, &act, &oact) < 0) { - return (void*)SIG_ERR; + if (sigaction(signo, &act, NULL) < 0) { + return FAILURE; } -#ifdef HAVE_STRUCT_SIGINFO_T - return oact.sa_sigaction; -#else - return oact.sa_handler; -#endif + /* Ensure this signal is not blocked */ + sigemptyset(&sigset); + sigaddset(&sigset, signo); + php_sigprocmask(SIG_UNBLOCK, &sigset, NULL); + + return SUCCESS; } -Sigfunc *php_signal(int signo, Sigfunc *func, int restart) +int php_signal(int signo, Sigfunc *func, int restart) { return php_signal4(signo, func, restart, 0); } diff --git a/ext/pcntl/php_signal.h b/ext/pcntl/php_signal.h index 21dbf0d2546e..4bff5b14b795 100644 --- a/ext/pcntl/php_signal.h +++ b/ext/pcntl/php_signal.h @@ -23,7 +23,7 @@ typedef void Sigfunc(int, siginfo_t*, void*); #else typedef void Sigfunc(int); #endif -Sigfunc *php_signal(int signo, Sigfunc *func, int restart); -Sigfunc *php_signal4(int signo, Sigfunc *func, int restart, int mask_all); +int php_signal(int signo, Sigfunc *func, int restart); +int php_signal4(int signo, Sigfunc *func, int restart, int mask_all); #endif From 094bf388611f4e464ecd044406a05d8ce0787aba Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Mon, 18 May 2020 09:56:41 +0200 Subject: [PATCH 05/11] Don't use Zend signal handling in phpdbg One difference between `zend_signal`, etc. and the underlying platform APIs like `signal` is that the Zend versions did automatically unblock the signals for which a handler is set. But looking at phpdbg, I don't think it is really the intention to unblock SIGIO or SIGSEGV when installing handlers for them. There is no good reason why all these signals would be blocked anyways. --- sapi/phpdbg/phpdbg.c | 22 ++++++++-------------- sapi/phpdbg/phpdbg.h | 1 - 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/sapi/phpdbg/phpdbg.c b/sapi/phpdbg/phpdbg.c index ee2483c1fb50..d95c1196efe2 100644 --- a/sapi/phpdbg/phpdbg.c +++ b/sapi/phpdbg/phpdbg.c @@ -1242,7 +1242,7 @@ void phpdbg_signal_handler(int sig, siginfo_t *info, void *context) /* {{{ */ if (PHPDBG_G(sigsegv_bailout)) { LONGJMP(*PHPDBG_G(sigsegv_bailout), FAILURE); } - zend_sigaction(sig, &PHPDBG_G(old_sigsegv_signal), NULL); + sigaction(sig, &PHPDBG_G(old_sigsegv_signal), NULL); } break; } @@ -1371,8 +1371,6 @@ int main(int argc, char **argv) /* {{{ */ # endif #endif - zend_signal_startup(); - ini_entries = NULL; ini_entries_len = 0; ini_ignore = 0; @@ -1669,10 +1667,6 @@ int main(int argc, char **argv) /* {{{ */ goto free_and_return; } - zend_try { - zend_signal_activate(); - } zend_end_try(); - /* setup remote server if necessary */ if (cleaning <= 0 && listen > 0) { server = phpdbg_open_socket(address, listen); @@ -1681,7 +1675,7 @@ int main(int argc, char **argv) /* {{{ */ } #ifndef _WIN32 - zend_sigaction(SIGIO, &sigio_struct, NULL); + sigaction(SIGIO, &sigio_struct, NULL); #endif /* set remote flag to stop service shutting down upon quit */ @@ -1689,7 +1683,7 @@ int main(int argc, char **argv) /* {{{ */ #ifndef _WIN32 } else { - zend_signal(SIGHUP, phpdbg_sighup_handler); + signal(SIGHUP, phpdbg_sighup_handler); #endif } @@ -1758,8 +1752,8 @@ int main(int argc, char **argv) /* {{{ */ } #ifndef _WIN32 - zend_try { zend_sigaction(SIGSEGV, &signal_struct, &PHPDBG_G(old_sigsegv_signal)); } zend_end_try(); - zend_try { zend_sigaction(SIGBUS, &signal_struct, &PHPDBG_G(old_sigsegv_signal)); } zend_end_try(); + sigaction(SIGSEGV, &signal_struct, &PHPDBG_G(old_sigsegv_signal)); + sigaction(SIGBUS, &signal_struct, &PHPDBG_G(old_sigsegv_signal)); #endif /* do not install sigint handlers for remote consoles */ @@ -1767,14 +1761,14 @@ int main(int argc, char **argv) /* {{{ */ #ifndef _WIN32 if (listen < 0) { #endif - zend_try { zend_signal(SIGINT, phpdbg_sigint_handler); } zend_end_try(); + signal(SIGINT, phpdbg_sigint_handler); #ifndef _WIN32 } /* setup io here */ if (remote) { PHPDBG_G(flags) |= PHPDBG_IS_REMOTE; - zend_signal(SIGPIPE, SIG_IGN); + signal(SIGPIPE, SIG_IGN); } PHPDBG_G(io)[PHPDBG_STDIN].ptr = stdin; PHPDBG_G(io)[PHPDBG_STDIN].fd = fileno(stdin); @@ -2107,7 +2101,7 @@ int main(int argc, char **argv) /* {{{ */ } #ifndef _WIN32 - /* force override (no zend_signals) to prevent crashes due to signal recursion in SIGSEGV/SIGBUS handlers */ + /* restore default SIGSEGV/SIGBUS handlers */ signal(SIGSEGV, SIG_DFL); signal(SIGBUS, SIG_DFL); diff --git a/sapi/phpdbg/phpdbg.h b/sapi/phpdbg/phpdbg.h index 5405155833cb..7e0f0b17f757 100644 --- a/sapi/phpdbg/phpdbg.h +++ b/sapi/phpdbg/phpdbg.h @@ -43,7 +43,6 @@ #include "zend_globals.h" #include "zend_ini_scanner.h" #include "zend_stream.h" -#include "zend_signal.h" #if !defined(_WIN32) && !defined(ZEND_SIGNALS) # include #elif defined(PHP_WIN32) From ae250a4625465c69c549ade66e8d8b78ab450b84 Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Mon, 18 May 2020 10:03:10 +0200 Subject: [PATCH 06/11] Rip out Zend signal handling --- Zend/Zend.m4 | 17 +- Zend/zend.c | 3 - Zend/zend.h | 1 - Zend/zend_signal.c | 448 ------------------ Zend/zend_signal.h | 112 ----- configure.ac | 2 +- ext/opcache/ZendAccelerator.c | 15 - ext/standard/info.c | 6 - .../tests/general_functions/phpinfo.phpt | 1 - main/main.c | 12 - sapi/apache2handler/sapi_apache2.c | 12 - sapi/cgi/cgi_main.c | 4 - sapi/cli/php_cli.c | 2 - sapi/cli/php_cli_server.c | 2 - sapi/embed/php_embed.c | 2 - sapi/fpm/fpm/fpm_main.c | 2 - sapi/fpm/fpm/fpm_signals.c | 2 - sapi/fuzzer/fuzzer-sapi.c | 6 - sapi/litespeed/lsapi_main.c | 6 - sapi/phpdbg/phpdbg.h | 6 +- 20 files changed, 5 insertions(+), 656 deletions(-) delete mode 100644 Zend/zend_signal.c delete mode 100644 Zend/zend_signal.h diff --git a/Zend/Zend.m4 b/Zend/Zend.m4 index 7c715e853bf5..6dbe1bdfdfa4 100644 --- a/Zend/Zend.m4 +++ b/Zend/Zend.m4 @@ -303,22 +303,7 @@ AC_MSG_RESULT(done) AC_CHECK_FUNCS(mremap) -AC_ARG_ENABLE([zend-signals], - [AS_HELP_STRING([--disable-zend-signals], - [whether to enable zend signal handling])], - [ZEND_SIGNALS=$enableval], - [ZEND_SIGNALS=yes]) - -AC_CHECK_FUNCS([sigaction], [], [ - ZEND_SIGNALS=no -]) -if test "$ZEND_SIGNALS" = "yes"; then - AC_DEFINE(ZEND_SIGNALS, 1, [Use zend signal handling]) - CFLAGS="$CFLAGS -DZEND_SIGNALS" -fi - -AC_MSG_CHECKING(whether to enable zend signal handling) -AC_MSG_RESULT($ZEND_SIGNALS) +AC_CHECK_FUNCS(sigaction) ]) diff --git a/Zend/zend.c b/Zend/zend.c index 4a9c939aa003..2c35ddbadfa8 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -164,9 +164,6 @@ ZEND_INI_BEGIN() STD_ZEND_INI_BOOLEAN("zend.multibyte", "0", ZEND_INI_PERDIR, OnUpdateBool, multibyte, zend_compiler_globals, compiler_globals) ZEND_INI_ENTRY("zend.script_encoding", NULL, ZEND_INI_ALL, OnUpdateScriptEncoding) STD_ZEND_INI_BOOLEAN("zend.detect_unicode", "1", ZEND_INI_ALL, OnUpdateBool, detect_unicode, zend_compiler_globals, compiler_globals) -#ifdef ZEND_SIGNALS - STD_ZEND_INI_BOOLEAN("zend.signal_check", "0", ZEND_INI_SYSTEM, OnUpdateBool, check, zend_signal_globals_t, zend_signal_globals) -#endif STD_ZEND_INI_BOOLEAN("zend.exception_ignore_args", "0", ZEND_INI_ALL, OnUpdateBool, exception_ignore_args, zend_executor_globals, executor_globals) ZEND_INI_END() diff --git a/Zend/zend.h b/Zend/zend.h index 33cd2eca0a41..591d4e86a0bd 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -38,7 +38,6 @@ #include "zend_stream.h" #include "zend_smart_str_public.h" #include "zend_smart_string_public.h" -#include "zend_signal.h" #define zend_sprintf sprintf diff --git a/Zend/zend_signal.c b/Zend/zend_signal.c deleted file mode 100644 index 96870f8d5cc4..000000000000 --- a/Zend/zend_signal.c +++ /dev/null @@ -1,448 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Zend Signal Handling | - +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Lucas Nealan | - | Arnaud Le Blanc | - +----------------------------------------------------------------------+ - - This software was contributed to PHP by Facebook Inc. in 2008. - - Future revisions and derivatives of this source code must acknowledge - Facebook Inc. as the original contributor of this module by leaving - this note intact in the source code. - - All other licensing and usage conditions are those of the PHP Group. -*/ - -#define _GNU_SOURCE -#include - -#include "zend.h" -#include "zend_globals.h" -#include - -#ifdef HAVE_UNISTD_H -#include -#endif - -#ifdef ZEND_SIGNALS - -#include "zend_signal.h" - -#ifdef ZTS -ZEND_API int zend_signal_globals_id; -ZEND_API size_t zend_signal_globals_offset; -#else -ZEND_API zend_signal_globals_t zend_signal_globals; -#endif /* not ZTS */ - -#define SIGNAL_BEGIN_CRITICAL() \ - sigset_t oldmask; \ - zend_sigprocmask(SIG_BLOCK, &global_sigmask, &oldmask); -#define SIGNAL_END_CRITICAL() \ - zend_sigprocmask(SIG_SETMASK, &oldmask, NULL); - -#ifdef ZTS -# define zend_sigprocmask(signo, set, oldset) tsrm_sigmask((signo), (set), (oldset)) -#else -# define zend_sigprocmask(signo, set, oldset) sigprocmask((signo), (set), (oldset)) -#endif - -static void zend_signal_handler(int signo, siginfo_t *siginfo, void *context); -static int zend_signal_register(int signo, void (*handler)(int, siginfo_t*, void*)); - -#ifdef __CYGWIN__ -#define TIMEOUT_SIG SIGALRM -#else -#define TIMEOUT_SIG SIGPROF -#endif - -static int zend_sigs[] = { TIMEOUT_SIG, SIGHUP, SIGINT, SIGQUIT, SIGTERM, SIGUSR1, SIGUSR2 }; - -#define SA_FLAGS_MASK ~(SA_NODEFER | SA_RESETHAND) - -/* True globals, written only at process startup */ -static zend_signal_entry_t global_orig_handlers[NSIG]; -static sigset_t global_sigmask; - -/* {{{ zend_signal_handler_defer - * Blocks signals if in critical section */ -void zend_signal_handler_defer(int signo, siginfo_t *siginfo, void *context) -{ - int errno_save = errno; - zend_signal_queue_t *queue, *qtmp; - -#ifdef ZTS - /* A signal could hit after TSRM shutdown, in this case globals are already freed. */ - if (tsrm_is_shutdown()) { - /* Forward to default handler handler */ - zend_signal_handler(signo, siginfo, context); - return; - } -#endif - - if (EXPECTED(SIGG(active))) { - if (UNEXPECTED(SIGG(depth) == 0)) { /* try to handle signal */ - if (UNEXPECTED(SIGG(blocked))) { - SIGG(blocked) = 0; - } - if (EXPECTED(SIGG(running) == 0)) { - SIGG(running) = 1; - zend_signal_handler(signo, siginfo, context); - - queue = SIGG(phead); - SIGG(phead) = NULL; - - while (queue) { - zend_signal_handler(queue->zend_signal.signo, queue->zend_signal.siginfo, queue->zend_signal.context); - qtmp = queue->next; - queue->next = SIGG(pavail); - queue->zend_signal.signo = 0; - SIGG(pavail) = queue; - queue = qtmp; - } - SIGG(running) = 0; - } - } else { /* delay signal handling */ - SIGG(blocked) = 1; /* signal is blocked */ - - if ((queue = SIGG(pavail))) { /* if none available it's simply forgotton */ - SIGG(pavail) = queue->next; - queue->zend_signal.signo = signo; - queue->zend_signal.siginfo = siginfo; - queue->zend_signal.context = context; - queue->next = NULL; - - if (SIGG(phead) && SIGG(ptail)) { - SIGG(ptail)->next = queue; - } else { - SIGG(phead) = queue; - } - SIGG(ptail) = queue; - } -#if ZEND_DEBUG - else { /* this may not be safe to do, but could work and be useful */ - zend_output_debug_string(0, "zend_signal: not enough queue storage, lost signal (%d)", signo); - } -#endif - } - } else { - /* need to just run handler if we're inactive and getting a signal */ - zend_signal_handler(signo, siginfo, context); - } - - errno = errno_save; -} /* }}} */ - -/* {{{ zend_signal_handler_unblock - * Handle deferred signal from HANDLE_UNBLOCK_ALARMS */ -ZEND_API void zend_signal_handler_unblock(void) -{ - zend_signal_queue_t *queue; - zend_signal_t zend_signal; - - if (EXPECTED(SIGG(active))) { - SIGNAL_BEGIN_CRITICAL(); /* procmask to protect handler_defer as if it were called by the kernel */ - queue = SIGG(phead); - SIGG(phead) = queue->next; - zend_signal = queue->zend_signal; - queue->next = SIGG(pavail); - queue->zend_signal.signo = 0; - SIGG(pavail) = queue; - - zend_signal_handler_defer(zend_signal.signo, zend_signal.siginfo, zend_signal.context); - SIGNAL_END_CRITICAL(); - } -} -/* }}} */ - -/* {{{ zend_signal_handler - * Call the previously registered handler for a signal - */ -static void zend_signal_handler(int signo, siginfo_t *siginfo, void *context) -{ - int errno_save = errno; - struct sigaction sa; - sigset_t sigset; - zend_signal_entry_t p_sig; -#ifdef ZTS - if (tsrm_is_shutdown()) { - p_sig.flags = 0; - p_sig.handler = SIG_DFL; - } else -#endif - p_sig = SIGG(handlers)[signo-1]; - - if (p_sig.handler == SIG_DFL) { /* raise default handler */ - if (sigaction(signo, NULL, &sa) == 0) { - sa.sa_handler = SIG_DFL; - sigemptyset(&sa.sa_mask); - - sigemptyset(&sigset); - sigaddset(&sigset, signo); - - if (sigaction(signo, &sa, NULL) == 0) { - /* throw away any blocked signals */ - zend_sigprocmask(SIG_UNBLOCK, &sigset, NULL); -#ifdef ZTS -# define RAISE_ERROR "raise() failed\n" - if (raise(signo) != 0) { - /* On some systems raise() fails with errno 3: No such process */ - kill(getpid(), signo); - } -#else - kill(getpid(), signo); -#endif - } - } - } else if (p_sig.handler != SIG_IGN) { - if (p_sig.flags & SA_SIGINFO) { - if (p_sig.flags & SA_RESETHAND) { - SIGG(handlers)[signo-1].flags = 0; - SIGG(handlers)[signo-1].handler = SIG_DFL; - } - (*(void (*)(int, siginfo_t*, void*))p_sig.handler)(signo, siginfo, context); - } else { - (*(void (*)(int))p_sig.handler)(signo); - } - } - - errno = errno_save; -} /* }}} */ - -/* {{{ zend_sigaction - * Register a signal handler that will be deferred in critical sections */ -ZEND_API int zend_sigaction(int signo, const struct sigaction *act, struct sigaction *oldact) -{ - struct sigaction sa; - sigset_t sigset; - - if (oldact != NULL) { - oldact->sa_flags = SIGG(handlers)[signo-1].flags; - oldact->sa_handler = (void *) SIGG(handlers)[signo-1].handler; - oldact->sa_mask = global_sigmask; - } - if (act != NULL) { - SIGG(handlers)[signo-1].flags = act->sa_flags; - if (act->sa_flags & SA_SIGINFO) { - SIGG(handlers)[signo-1].handler = (void *) act->sa_sigaction; - } else { - SIGG(handlers)[signo-1].handler = (void *) act->sa_handler; - } - - memset(&sa, 0, sizeof(sa)); - if (SIGG(handlers)[signo-1].handler == (void *) SIG_IGN) { - sa.sa_sigaction = (void *) SIG_IGN; - } else { - sa.sa_flags = SA_SIGINFO | (act->sa_flags & SA_FLAGS_MASK); - sa.sa_sigaction = zend_signal_handler_defer; - sa.sa_mask = global_sigmask; - } - - if (sigaction(signo, &sa, NULL) < 0) { - zend_error_noreturn(E_ERROR, "Error installing signal handler for %d", signo); - } - - /* unsure this signal is not blocked */ - sigemptyset(&sigset); - sigaddset(&sigset, signo); - zend_sigprocmask(SIG_UNBLOCK, &sigset, NULL); - } - - return SUCCESS; -} -/* }}} */ - -/* {{{ zend_signal - * Register a signal handler that will be deferred in critical sections */ -ZEND_API int zend_signal(int signo, void (*handler)(int)) -{ - struct sigaction sa; - - memset(&sa, 0, sizeof(sa)); - sa.sa_flags = 0; - sa.sa_handler = handler; - sa.sa_mask = global_sigmask; - - return zend_sigaction(signo, &sa, NULL); -} -/* }}} */ - -/* {{{ zend_signal_register - * Set a handler for a signal we want to defer. - * Previously set handler must have been saved before. - */ -static int zend_signal_register(int signo, void (*handler)(int, siginfo_t*, void*)) -{ - struct sigaction sa; - - if (sigaction(signo, NULL, &sa) == 0) { - if ((sa.sa_flags & SA_SIGINFO) && sa.sa_sigaction == handler) { - return FAILURE; - } - - SIGG(handlers)[signo-1].flags = sa.sa_flags; - if (sa.sa_flags & SA_SIGINFO) { - SIGG(handlers)[signo-1].handler = (void *)sa.sa_sigaction; - } else { - SIGG(handlers)[signo-1].handler = (void *)sa.sa_handler; - } - - sa.sa_flags = SA_SIGINFO; /* we'll use a siginfo handler */ - sa.sa_sigaction = handler; - sa.sa_mask = global_sigmask; - - if (sigaction(signo, &sa, NULL) < 0) { - zend_error_noreturn(E_ERROR, "Error installing signal handler for %d", signo); - } - - return SUCCESS; - } - return FAILURE; -} /* }}} */ - -/* {{{ zend_signal_activate - * Install our signal handlers, per request */ -void zend_signal_activate(void) -{ - size_t x; - - memcpy(&SIGG(handlers), &global_orig_handlers, sizeof(global_orig_handlers)); - - if (SIGG(reset)) { - for (x = 0; x < sizeof(zend_sigs) / sizeof(*zend_sigs); x++) { - zend_signal_register(zend_sigs[x], zend_signal_handler_defer); - } - } - - SIGG(active) = 1; - SIGG(depth) = 0; - SIGG(check) = ZEND_DEBUG; -} /* }}} */ - -/* {{{ zend_signal_deactivate - * */ -void zend_signal_deactivate(void) -{ - if (SIGG(check)) { - size_t x; - struct sigaction sa; - - if (SIGG(depth) != 0) { - zend_error(E_CORE_WARNING, "zend_signal: shutdown with non-zero blocking depth (%d)", SIGG(depth)); - } - - /* did anyone steal our installed handler */ - for (x = 0; x < sizeof(zend_sigs) / sizeof(*zend_sigs); x++) { - sigaction(zend_sigs[x], NULL, &sa); - if (sa.sa_sigaction != zend_signal_handler_defer && - sa.sa_sigaction != (void *) SIG_IGN) { - zend_error(E_CORE_WARNING, "zend_signal: handler was replaced for signal (%d) after startup", zend_sigs[x]); - } - } - } - - /* After active=0 is set, signal handlers will be called directly and other - * state that is reset below will not be accessed. */ - *((volatile int *) &SIGG(active)) = 0; - - SIGG(running) = 0; - SIGG(blocked) = 0; - SIGG(depth) = 0; - - /* If there are any queued signals because of a missed unblock, drop them. */ - if (SIGG(phead) && SIGG(ptail)) { - SIGG(ptail)->next = SIGG(pavail); - SIGG(pavail) = SIGG(phead); - SIGG(phead) = NULL; - SIGG(ptail) = NULL; - } -} -/* }}} */ - -static void zend_signal_globals_ctor(zend_signal_globals_t *zend_signal_globals) /* {{{ */ -{ - size_t x; - - memset(zend_signal_globals, 0, sizeof(*zend_signal_globals)); - zend_signal_globals->reset = 1; - - for (x = 0; x < sizeof(zend_signal_globals->pstorage) / sizeof(*zend_signal_globals->pstorage); ++x) { - zend_signal_queue_t *queue = &zend_signal_globals->pstorage[x]; - queue->zend_signal.signo = 0; - queue->next = zend_signal_globals->pavail; - zend_signal_globals->pavail = queue; - } -} -/* }}} */ - -void zend_signal_init(void) /* {{{ */ -{ - int signo; - struct sigaction sa; - - /* Save previously registered signal handlers into orig_handlers */ - memset(&global_orig_handlers, 0, sizeof(global_orig_handlers)); - for (signo = 1; signo < NSIG; ++signo) { - if (sigaction(signo, NULL, &sa) == 0) { - global_orig_handlers[signo-1].flags = sa.sa_flags; - if (sa.sa_flags & SA_SIGINFO) { - global_orig_handlers[signo-1].handler = (void *) sa.sa_sigaction; - } else { - global_orig_handlers[signo-1].handler = (void *) sa.sa_handler; - } - } - } -} -/* }}} */ - -/* {{{ zend_signal_startup - * alloc zend signal globals */ -ZEND_API void zend_signal_startup(void) -{ - -#ifdef ZTS - ts_allocate_fast_id(&zend_signal_globals_id, &zend_signal_globals_offset, sizeof(zend_signal_globals_t), (ts_allocate_ctor) zend_signal_globals_ctor, NULL); -#else - zend_signal_globals_ctor(&zend_signal_globals); -#endif - - /* Used to block signals during execution of signal handlers */ - sigfillset(&global_sigmask); - sigdelset(&global_sigmask, SIGILL); - sigdelset(&global_sigmask, SIGABRT); - sigdelset(&global_sigmask, SIGFPE); - sigdelset(&global_sigmask, SIGKILL); - sigdelset(&global_sigmask, SIGSEGV); - sigdelset(&global_sigmask, SIGCONT); - sigdelset(&global_sigmask, SIGSTOP); - sigdelset(&global_sigmask, SIGTSTP); - sigdelset(&global_sigmask, SIGTTIN); - sigdelset(&global_sigmask, SIGTTOU); -#ifdef SIGBUS - sigdelset(&global_sigmask, SIGBUS); -#endif -#ifdef SIGSYS - sigdelset(&global_sigmask, SIGSYS); -#endif -#ifdef SIGTRAP - sigdelset(&global_sigmask, SIGTRAP); -#endif - - zend_signal_init(); -} -/* }}} */ - - -#endif /* ZEND_SIGNALS */ diff --git a/Zend/zend_signal.h b/Zend/zend_signal.h deleted file mode 100644 index 0bb191db7324..000000000000 --- a/Zend/zend_signal.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Zend Signal Handling | - +----------------------------------------------------------------------+ - | Copyright (c) The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Lucas Nealan | - | Arnaud Le Blanc | - +----------------------------------------------------------------------+ - - */ - -#ifndef ZEND_SIGNAL_H -#define ZEND_SIGNAL_H - -#ifdef ZEND_SIGNALS - -#include - -#ifndef NSIG -#define NSIG 65 -#endif - -#ifndef ZEND_SIGNAL_QUEUE_SIZE -#define ZEND_SIGNAL_QUEUE_SIZE 64 -#endif - -/* Signal structs */ -typedef struct _zend_signal_entry_t { - int flags; /* sigaction style flags */ - void* handler; /* signal handler or context */ -} zend_signal_entry_t; - -typedef struct _zend_signal_t { - int signo; - siginfo_t *siginfo; - void* context; -} zend_signal_t; - -typedef struct _zend_signal_queue_t { - zend_signal_t zend_signal; - struct _zend_signal_queue_t *next; -} zend_signal_queue_t; - -/* Signal Globals */ -typedef struct _zend_signal_globals_t { - int depth; - int blocked; /* 1==TRUE, 0==FALSE */ - int running; /* in signal handler execution */ - int active; /* internal signal handling is enabled */ - zend_bool check; /* check for replaced handlers on shutdown */ - zend_bool reset; /* reset signal handlers on each request */ - zend_signal_entry_t handlers[NSIG]; - zend_signal_queue_t pstorage[ZEND_SIGNAL_QUEUE_SIZE], *phead, *ptail, *pavail; /* pending queue */ -} zend_signal_globals_t; - -# ifdef ZTS -# define SIGG(v) ZEND_TSRMG_FAST(zend_signal_globals_offset, zend_signal_globals_t *, v) -BEGIN_EXTERN_C() -ZEND_API extern int zend_signal_globals_id; -ZEND_API extern size_t zend_signal_globals_offset; -END_EXTERN_C() -# else -# define SIGG(v) (zend_signal_globals.v) -BEGIN_EXTERN_C() -ZEND_API extern zend_signal_globals_t zend_signal_globals; -END_EXTERN_C() -# endif /* not ZTS */ - -# ifdef ZTS -# define ZEND_SIGNAL_BLOCK_INTERRUPTIONS() if (EXPECTED(zend_signal_globals_id)) { SIGG(depth)++; } -# define ZEND_SIGNAL_UNBLOCK_INTERRUPTIONS() if (EXPECTED(zend_signal_globals_id) && UNEXPECTED(((SIGG(depth)--) == SIGG(blocked)))) { zend_signal_handler_unblock(); } -# else /* ZTS */ -# define ZEND_SIGNAL_BLOCK_INTERRUPTIONS() SIGG(depth)++; -# define ZEND_SIGNAL_UNBLOCK_INTERRUPTIONS() if (((SIGG(depth)--) == SIGG(blocked))) { zend_signal_handler_unblock(); } -# endif /* not ZTS */ - -ZEND_API void zend_signal_handler_unblock(void); -void zend_signal_activate(void); -void zend_signal_deactivate(void); -BEGIN_EXTERN_C() -ZEND_API void zend_signal_startup(void); -END_EXTERN_C() -void zend_signal_init(void); - -ZEND_API int zend_signal(int signo, void (*handler)(int)); -ZEND_API int zend_sigaction(int signo, const struct sigaction *act, struct sigaction *oldact); - -#else /* ZEND_SIGNALS */ - -# define ZEND_SIGNAL_BLOCK_INTERRUPTIONS() -# define ZEND_SIGNAL_UNBLOCK_INTERRUPTIONS() - -# define zend_signal_activate() -# define zend_signal_deactivate() -# define zend_signal_startup() -# define zend_signal_init() - -# define zend_signal(signo, handler) signal(signo, handler) -# define zend_sigaction(signo, act, oldact) sigaction(signo, act, oldact) - -#endif /* ZEND_SIGNALS */ - -#endif /* ZEND_SIGNAL_H */ diff --git a/configure.ac b/configure.ac index 2c3928b6a967..b94cd0093c4a 100644 --- a/configure.ac +++ b/configure.ac @@ -1472,7 +1472,7 @@ PHP_ADD_SOURCES(Zend, \ zend_list.c zend_builtin_functions.c \ zend_ini.c zend_sort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_gc.c \ - zend_closures.c zend_weakrefs.c zend_float.c zend_string.c zend_signal.c zend_generators.c \ + zend_closures.c zend_weakrefs.c zend_float.c zend_string.c zend_generators.c \ zend_virtual_cwd.c zend_ast.c zend_objects.c zend_object_handlers.c zend_objects_API.c \ zend_default_classes.c zend_inheritance.c zend_smart_str.c zend_cpuinfo.c zend_gdb.c, \ -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 506971e3b668..9631f7bc2a55 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -4862,9 +4862,6 @@ static int accel_finish_startup(void) size_t (*orig_ub_write)(const char *str, size_t str_length) = sapi_module.ub_write; void (*orig_flush)(void *server_context) = sapi_module.flush; uint32_t orig_compiler_options = CG(compiler_options); -#ifdef ZEND_SIGNALS - zend_bool old_reset_signals = SIGG(reset); -#endif if (UNEXPECTED(file_cache_only)) { zend_accel_error(ACCEL_LOG_WARNING, "Preloading doesn't work in \"file_cache_only\" mode"); @@ -4967,10 +4964,6 @@ static int accel_finish_startup(void) zend_interned_strings_switch_storage(1); -#ifdef ZEND_SIGNALS - SIGG(reset) = 0; -#endif - orig_error_reporting = EG(error_reporting); EG(error_reporting) = 0; @@ -5003,20 +4996,12 @@ static int accel_finish_startup(void) orig_report_memleaks = PG(report_memleaks); PG(report_memleaks) = 0; -#ifdef ZEND_SIGNALS - /* We may not have registered signal handlers due to SIGG(reset)=0, so - * also disable the check that they are registered. */ - SIGG(check) = 0; -#endif php_request_shutdown(NULL); /* calls zend_shared_alloc_unlock(); */ PG(report_memleaks) = orig_report_memleaks; } else { zend_shared_alloc_unlock(); ret = FAILURE; } -#ifdef ZEND_SIGNALS - SIGG(reset) = old_reset_signals; -#endif CG(compiler_options) = orig_compiler_options; diff --git a/ext/standard/info.c b/ext/standard/info.c index 8a090d20e538..745285f28647 100644 --- a/ext/standard/info.c +++ b/ext/standard/info.c @@ -848,12 +848,6 @@ PHPAPI ZEND_COLD void php_print_info(int flag) php_info_print_table_row(2, "Thread Safety", "disabled" ); #endif -#ifdef ZEND_SIGNALS - php_info_print_table_row(2, "Zend Signal Handling", "enabled" ); -#else - php_info_print_table_row(2, "Zend Signal Handling", "disabled" ); -#endif - php_info_print_table_row(2, "Zend Memory Manager", is_zend_mm() ? "enabled" : "disabled" ); { diff --git a/ext/standard/tests/general_functions/phpinfo.phpt b/ext/standard/tests/general_functions/phpinfo.phpt index 5f4d99ffbaf2..56c76090376a 100644 --- a/ext/standard/tests/general_functions/phpinfo.phpt +++ b/ext/standard/tests/general_functions/phpinfo.phpt @@ -31,7 +31,6 @@ Zend Extension Build => API%s PHP Extension Build => API%s Debug Build => %s Thread Safety => %s%A -Zend Signal Handling => %s Zend Memory Manager => %s Zend Multibyte Support => %s IPv6 Support => %s diff --git a/main/main.c b/main/main.c index 6143718d05d4..af4fc1c681be 100644 --- a/main/main.c +++ b/main/main.c @@ -1763,10 +1763,6 @@ int php_request_startup(void) zend_activate(); sapi_activate(); -#ifdef ZEND_SIGNALS - zend_signal_activate(); -#endif - if (PG(max_input_time) == -1) { zend_set_timeout(EG(timeout_seconds), 1); } else { @@ -1913,11 +1909,6 @@ void php_request_shutdown(void *dummy) shutdown_memory_manager(CG(unclean_shutdown) || !report_memleaks, 0); } zend_end_try(); - /* 16. Deactivate Zend signals */ -#ifdef ZEND_SIGNALS - zend_signal_deactivate(); -#endif - #ifdef PHP_WIN32 if (PG(com_initialized)) { CoUninitialize(); @@ -2740,9 +2731,6 @@ PHPAPI void php_reserve_tsrm_memory(void) TSRM_ALIGNED_SIZE(sizeof(zend_php_scanner_globals)) + TSRM_ALIGNED_SIZE(sizeof(zend_ini_scanner_globals)) + TSRM_ALIGNED_SIZE(sizeof(virtual_cwd_globals)) + -#ifdef ZEND_SIGNALS - TSRM_ALIGNED_SIZE(sizeof(zend_signal_globals_t)) + -#endif TSRM_ALIGNED_SIZE(zend_mm_globals_size()) + TSRM_ALIGNED_SIZE(zend_gc_globals_size()) + TSRM_ALIGNED_SIZE(sizeof(php_core_globals)) + diff --git a/sapi/apache2handler/sapi_apache2.c b/sapi/apache2handler/sapi_apache2.c index b2f32ce49a1a..7fd49d1b1966 100644 --- a/sapi/apache2handler/sapi_apache2.c +++ b/sapi/apache2handler/sapi_apache2.c @@ -478,8 +478,6 @@ php_apache_server_startup(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp # endif #endif - zend_signal_startup(); - sapi_startup(&apache2_sapi_module); if (apache2_sapi_module.startup(&apache2_sapi_module) != SUCCESS) { return DONE; @@ -733,20 +731,10 @@ static void php_apache_child_init(apr_pool_t *pchild, server_rec *s) apr_pool_cleanup_register(pchild, NULL, php_apache_child_shutdown, apr_pool_cleanup_null); } -#ifdef ZEND_SIGNALS -static void php_apache_signal_init(apr_pool_t *pchild, server_rec *s) -{ - zend_signal_init(); -} -#endif - void php_ap2_register_hook(apr_pool_t *p) { ap_hook_pre_config(php_pre_config, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_post_config(php_apache_server_startup, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_handler(php_handler, NULL, NULL, APR_HOOK_MIDDLE); -#ifdef ZEND_SIGNALS - ap_hook_child_init(php_apache_signal_init, NULL, NULL, APR_HOOK_MIDDLE); -#endif ap_hook_child_init(php_apache_child_init, NULL, NULL, APR_HOOK_MIDDLE); } diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c index 88dad39bbd9d..8b65da447860 100644 --- a/sapi/cgi/cgi_main.c +++ b/sapi/cgi/cgi_main.c @@ -1792,8 +1792,6 @@ int main(int argc, char *argv[]) # endif #endif - zend_signal_startup(); - #ifdef ZTS ts_allocate_id(&php_cgi_globals_id, sizeof(php_cgi_globals_struct), (ts_allocate_ctor) php_cgi_globals_ctor, NULL); #else @@ -2077,7 +2075,6 @@ consult the installation file that came with this distribution, or visit \n\ sigaction(SIGTERM, &old_term, 0); sigaction(SIGQUIT, &old_quit, 0); sigaction(SIGINT, &old_int, 0); - zend_signal_init(); break; case -1: perror("php (pre-forking)"); @@ -2117,7 +2114,6 @@ consult the installation file that came with this distribution, or visit \n\ } } else { parent = 0; - zend_signal_init(); } #else diff --git a/sapi/cli/php_cli.c b/sapi/cli/php_cli.c index a5fafda4f1d3..3de40f9cca9c 100644 --- a/sapi/cli/php_cli.c +++ b/sapi/cli/php_cli.c @@ -1213,8 +1213,6 @@ int main(int argc, char *argv[]) # endif #endif - zend_signal_startup(); - #ifdef PHP_WIN32 _fmode = _O_BINARY; /*sets default for file streams to binary */ setmode(_fileno(stdin), O_BINARY); /* make the stdio mode be binary */ diff --git a/sapi/cli/php_cli_server.c b/sapi/cli/php_cli_server.c index dbee30700f83..86d8f9f5e1eb 100644 --- a/sapi/cli/php_cli_server.c +++ b/sapi/cli/php_cli_server.c @@ -2725,8 +2725,6 @@ int do_cli_server(int argc, char **argv) /* {{{ */ signal(SIGPIPE, SIG_IGN); #endif - zend_signal_init(); - php_cli_server_do_event_loop(&server); php_cli_server_dtor(&server); return 0; diff --git a/sapi/embed/php_embed.c b/sapi/embed/php_embed.c index 1713534a23d8..ba27310eb133 100644 --- a/sapi/embed/php_embed.c +++ b/sapi/embed/php_embed.c @@ -173,8 +173,6 @@ EMBED_SAPI_API int php_embed_init(int argc, char **argv) # endif #endif - zend_signal_startup(); - sapi_startup(&php_embed_module); #ifdef PHP_WIN32 diff --git a/sapi/fpm/fpm/fpm_main.c b/sapi/fpm/fpm/fpm_main.c index 0d508dd04be9..79d1f45208eb 100644 --- a/sapi/fpm/fpm/fpm_main.c +++ b/sapi/fpm/fpm/fpm_main.c @@ -1570,8 +1570,6 @@ int main(int argc, char *argv[]) php_tsrm_startup(); #endif - zend_signal_startup(); - sapi_startup(&cgi_sapi_module); cgi_sapi_module.php_ini_path_override = NULL; cgi_sapi_module.php_ini_ignore_cwd = 1; diff --git a/sapi/fpm/fpm/fpm_signals.c b/sapi/fpm/fpm/fpm_signals.c index f5a5ae5ec174..75e076e07fa2 100644 --- a/sapi/fpm/fpm/fpm_signals.c +++ b/sapi/fpm/fpm/fpm_signals.c @@ -250,8 +250,6 @@ int fpm_signals_init_child() /* {{{ */ return -1; } - zend_signal_init(); - if (0 > fpm_signals_unblock()) { return -1; } diff --git a/sapi/fuzzer/fuzzer-sapi.c b/sapi/fuzzer/fuzzer-sapi.c index eb452788b107..8933972139da 100644 --- a/sapi/fuzzer/fuzzer-sapi.c +++ b/sapi/fuzzer/fuzzer-sapi.c @@ -147,12 +147,6 @@ int fuzzer_request_startup() return FAILURE; } -#ifdef ZEND_SIGNALS - /* Some signal handlers will be overridden, - * don't complain about them during shutdown. */ - SIGG(check) = 0; -#endif - return SUCCESS; } diff --git a/sapi/litespeed/lsapi_main.c b/sapi/litespeed/lsapi_main.c index 1a6527a68b65..40c4d4e5f6db 100644 --- a/sapi/litespeed/lsapi_main.c +++ b/sapi/litespeed/lsapi_main.c @@ -1483,12 +1483,6 @@ int main( int argc, char * argv[] ) php_tsrm_startup(); #endif -#if PHP_MAJOR_VERSION >= 7 -#if defined(ZEND_SIGNALS) || PHP_MINOR_VERSION > 0 - zend_signal_startup(); -#endif -#endif - if (argc > 1 ) { if ( parse_opt( argc, argv, &climode, &php_ini_path, &php_bind ) == -1 ) { diff --git a/sapi/phpdbg/phpdbg.h b/sapi/phpdbg/phpdbg.h index 7e0f0b17f757..247f42b69ac3 100644 --- a/sapi/phpdbg/phpdbg.h +++ b/sapi/phpdbg/phpdbg.h @@ -43,10 +43,10 @@ #include "zend_globals.h" #include "zend_ini_scanner.h" #include "zend_stream.h" -#if !defined(_WIN32) && !defined(ZEND_SIGNALS) -# include -#elif defined(PHP_WIN32) +#ifdef _WIN32 # include "win32/signal.h" +#else +# include #endif #include "SAPI.h" #include From ce002d482d15ddd80e36034b9f564b59be82e9e0 Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Tue, 19 May 2020 15:47:46 +0200 Subject: [PATCH 07/11] Move signal blocking and unblocking macros into zend_signal.h Also give them names which match the old ones from Zend signal handling. This will allow some extensions which used the old macros to continue working without change. --- Zend/zend.c | 22 ++++++++ Zend/zend.h | 4 ++ Zend/zend_signal.h | 60 ++++++++++++++++++++++ ext/opcache/ZendAccelerator.c | 95 +++++++++-------------------------- 4 files changed, 110 insertions(+), 71 deletions(-) create mode 100644 Zend/zend_signal.h diff --git a/Zend/zend.c b/Zend/zend.c index 2c35ddbadfa8..4c98ee396a9f 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -66,6 +66,24 @@ static uint32_t zend_version_info_length; #define ZEND_CORE_VERSION_INFO "Zend Engine v" ZEND_VERSION ", Copyright (c) Zend Technologies\n" #define PRINT_ZVAL_INDENT 4 +#ifdef HAVE_SIGPROCMASK +ZEND_API sigset_t mask_all_signals; /* For blocking/unblocking signals */ + +# if ZEND_DEBUG +/* Ensure that signal blocking macros in zend_signal.h are used correctly */ +ZEND_TLS int _signals_masked = 0; +ZEND_API void zend_debug_mask_signals() +{ + _signals_masked++; +} +ZEND_API void zend_debug_unmask_signals() +{ + if (--_signals_masked) + zend_error_noreturn(E_ERROR, "Cannot nest ZEND_SIGNAL_BLOCK_INTERRUPTIONS; it is not re-entrant"); +} +# endif +#endif + /* true multithread-shared globals */ ZEND_API zend_class_entry *zend_standard_class_def = NULL; ZEND_API size_t (*zend_printf)(const char *format, ...); @@ -803,6 +821,10 @@ int zend_startup(zend_utility_functions *utility_functions) /* {{{ */ fpsetmask(0); #endif +#ifdef HAVE_SIGPROCMASK + sigfillset(&mask_all_signals); +#endif + zend_startup_strtod(); zend_startup_extensions_mechanism(); diff --git a/Zend/zend.h b/Zend/zend.h index 591d4e86a0bd..68349aaae2dd 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -38,9 +38,13 @@ #include "zend_stream.h" #include "zend_smart_str_public.h" #include "zend_smart_string_public.h" +#include "zend_signal.h" #define zend_sprintf sprintf +#define HANDLE_BLOCK_INTERRUPTIONS() ZEND_SIGNAL_BLOCK_INTERRUPTIONS() +#define HANDLE_UNBLOCK_INTERRUPTIONS() ZEND_SIGNAL_UNBLOCK_INTERRUPTIONS() + #define INTERNAL_FUNCTION_PARAMETERS zend_execute_data *execute_data, zval *return_value #define INTERNAL_FUNCTION_PARAM_PASSTHRU execute_data, return_value diff --git a/Zend/zend_signal.h b/Zend/zend_signal.h new file mode 100644 index 000000000000..b66a9c582c39 --- /dev/null +++ b/Zend/zend_signal.h @@ -0,0 +1,60 @@ +/* + +----------------------------------------------------------------------+ + | Blocking and Unblocking Signals | + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + */ + +#ifndef ZEND_SIGNAL_H +#define ZEND_SIGNAL_H + +#include + +#ifdef HAVE_SIGPROCMASK + +extern sigset_t mask_all_signals; + +# if ZEND_DEBUG +ZEND_API void zend_debug_mask_signals(); +ZEND_API void zend_debug_unmask_signals(); +# else +# define zend_debug_mask_signals() do {} while (0) +# define zend_debug_unmask_signals() do {} while (0) +# endif + +# define ZEND_SIGNAL_BLOCK_INTERRUPTIONS() \ + sigset_t _oldmask; \ + zend_debug_mask_signals(); \ + MASK_ALL_SIGNALS() +# define ZEND_SIGNAL_UNBLOCK_INTERRUPTIONS() \ + zend_debug_unmask_signals(); \ + UNMASK_ALL_SIGNALS() + +# ifdef ZTS +# define MASK_ALL_SIGNALS() \ + tsrm_sigmask(SIG_BLOCK, &mask_all_signals, &_oldmask) +# define UNMASK_ALL_SIGNALS() \ + tsrm_sigmask(SIG_SETMASK, &_oldmask, NULL) +# else +# define MASK_ALL_SIGNALS() \ + sigprocmask(SIG_BLOCK, &mask_all_signals, &_oldmask) +# define UNMASK_ALL_SIGNALS() \ + sigprocmask(SIG_SETMASK, &_oldmask, NULL) +# endif + +#else + +# define ZEND_SIGNAL_BLOCK_INTERRUPTIONS() do {} while(0) +# define ZEND_SIGNAL_UNBLOCK_INTERRUPTIONS() do {} while(0) + +#endif /* HAVE_SIGPROCMASK */ +#endif /* ZEND_SIGNAL_H */ diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 9631f7bc2a55..62b3f816ba30 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -118,49 +118,6 @@ zend_bool file_cache_only = 0; /* process uses file cache only */ zend_bool fallback_process = 0; /* process uses file cache fallback */ #endif -#ifdef HAVE_SIGPROCMASK -static sigset_t mask_all_signals; - -# if ZEND_DEBUG -# ifdef ZTS - ZEND_TLS int _signals_masked = 0; -# else - static int _signals_masked = 0; -# endif -# define DEBUG_BLOCK_ALL_SIGNALS() _signals_masked += 1 -# define DEBUG_UNBLOCK_ALL_SIGNALS() \ - if (--_signals_masked) \ - zend_error_noreturn(E_ERROR, "Cannot nest BLOCK_ALL_SIGNALS; it is not re-entrant") -# else -# define DEBUG_BLOCK_ALL_SIGNALS() do {} while (0) -# define DEBUG_UNBLOCK_ALL_SIGNALS() do {} while (0) -# endif - -# define BLOCK_ALL_SIGNALS() \ - sigset_t _oldmask; \ - DEBUG_BLOCK_ALL_SIGNALS(); \ - MASK_ALL_SIGNALS() -# define UNBLOCK_ALL_SIGNALS() \ - DEBUG_UNBLOCK_ALL_SIGNALS(); \ - UNMASK_ALL_SIGNALS() - -# ifdef ZTS -# define MASK_ALL_SIGNALS() \ - tsrm_sigmask(SIG_BLOCK, &mask_all_signals, &_oldmask) -# define UNMASK_ALL_SIGNALS() \ - tsrm_sigmask(SIG_SETMASK, &_oldmask, NULL) -# else -# define MASK_ALL_SIGNALS() \ - sigprocmask(SIG_BLOCK, &mask_all_signals, &_oldmask) -# define UNMASK_ALL_SIGNALS() \ - sigprocmask(SIG_SETMASK, &_oldmask, NULL) -# endif - -#else -# define BLOCK_ALL_SIGNALS() do {} while(0) -# define UNBLOCK_ALL_SIGNALS() do {} while(0) -#endif - static zend_op_array *(*accelerator_orig_compile_file)(zend_file_handle *file_handle, int type); static int (*accelerator_orig_zend_stream_open_function)(const char *filename, zend_file_handle *handle ); static zend_string *(*accelerator_orig_zend_resolve_path)(const char *filename, size_t filename_len); @@ -788,7 +745,7 @@ static zend_string* ZEND_FASTCALL accel_replace_string_by_shm_permanent(zend_str static void accel_use_shm_interned_strings(void) { - BLOCK_ALL_SIGNALS(); + HANDLE_BLOCK_INTERRUPTIONS(); SHM_UNPROTECT(); zend_shared_alloc_lock(); @@ -803,7 +760,7 @@ static void accel_use_shm_interned_strings(void) zend_shared_alloc_unlock(); SHM_PROTECT(); - UNBLOCK_ALL_SIGNALS(); + HANDLE_UNBLOCK_INTERRUPTIONS(); } #ifndef ZEND_WIN32 @@ -1202,7 +1159,7 @@ char *accel_make_persistent_key(const char *path, size_t path_length, int *key_l zend_string *str = accel_find_interned_string(cwd_str); if (!str) { - BLOCK_ALL_SIGNALS(); + HANDLE_BLOCK_INTERRUPTIONS(); SHM_UNPROTECT(); zend_shared_alloc_lock(); str = accel_new_interned_string(zend_string_copy(cwd_str)); @@ -1212,7 +1169,7 @@ char *accel_make_persistent_key(const char *path, size_t path_length, int *key_l } zend_shared_alloc_unlock(); SHM_PROTECT(); - UNBLOCK_ALL_SIGNALS(); + HANDLE_UNBLOCK_INTERRUPTIONS(); } if (str) { char buf[32]; @@ -1246,7 +1203,7 @@ char *accel_make_persistent_key(const char *path, size_t path_length, int *key_l zend_string *str = accel_find_interned_string(ZCG(include_path)); if (!str) { - BLOCK_ALL_SIGNALS(); + HANDLE_BLOCK_INTERRUPTIONS(); SHM_UNPROTECT(); zend_shared_alloc_lock(); str = accel_new_interned_string(zend_string_copy(ZCG(include_path))); @@ -1255,7 +1212,7 @@ char *accel_make_persistent_key(const char *path, size_t path_length, int *key_l } zend_shared_alloc_unlock(); SHM_PROTECT(); - UNBLOCK_ALL_SIGNALS(); + HANDLE_UNBLOCK_INTERRUPTIONS(); } if (str) { char buf[32]; @@ -1352,7 +1309,7 @@ int zend_accel_invalidate(const char *filename, size_t filename_len, zend_bool f if (force || !ZCG(accel_directives).validate_timestamps || do_validate_timestamps(persistent_script, &file_handle) == FAILURE) { - BLOCK_ALL_SIGNALS(); + HANDLE_BLOCK_INTERRUPTIONS(); SHM_UNPROTECT(); zend_shared_alloc_lock(); if (!persistent_script->corrupted) { @@ -1367,7 +1324,7 @@ int zend_accel_invalidate(const char *filename, size_t filename_len, zend_bool f } zend_shared_alloc_unlock(); SHM_PROTECT(); - UNBLOCK_ALL_SIGNALS(); + HANDLE_UNBLOCK_INTERRUPTIONS(); } } @@ -1948,11 +1905,11 @@ zend_op_array *file_cache_compile_file(zend_file_handle *file_handle, int type) } } - BLOCK_ALL_SIGNALS(); + HANDLE_BLOCK_INTERRUPTIONS(); SHM_UNPROTECT(); persistent_script = zend_file_cache_script_load(file_handle); SHM_PROTECT(); - UNBLOCK_ALL_SIGNALS(); + HANDLE_UNBLOCK_INTERRUPTIONS(); if (persistent_script) { /* see bug #15471 (old BTS) */ if (persistent_script->script.filename) { @@ -2111,13 +2068,13 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) persistent_script = (zend_persistent_script *)bucket->data; if (key && !persistent_script->corrupted) { - BLOCK_ALL_SIGNALS(); + HANDLE_BLOCK_INTERRUPTIONS(); SHM_UNPROTECT(); zend_shared_alloc_lock(); zend_accel_add_key(key, key_length, bucket); zend_shared_alloc_unlock(); SHM_PROTECT(); - UNBLOCK_ALL_SIGNALS(); + HANDLE_UNBLOCK_INTERRUPTIONS(); } } } @@ -2162,7 +2119,7 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) return NULL; } - BLOCK_ALL_SIGNALS(); + HANDLE_BLOCK_INTERRUPTIONS(); SHM_UNPROTECT(); /* If script is found then validate_timestamps if option is enabled */ @@ -2225,7 +2182,7 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) /* No memory left. Behave like without the Accelerator */ if (ZSMMG(memory_exhausted) || ZCSG(restart_pending)) { SHM_PROTECT(); - UNBLOCK_ALL_SIGNALS(); + HANDLE_UNBLOCK_INTERRUPTIONS(); if (ZCG(accel_directives).file_cache) { return file_cache_compile_file(file_handle, type); } @@ -2233,9 +2190,9 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) } SHM_PROTECT(); - UNBLOCK_ALL_SIGNALS(); + HANDLE_UNBLOCK_INTERRUPTIONS(); persistent_script = opcache_compile_file(file_handle, type, key, &op_array); - BLOCK_ALL_SIGNALS(); + HANDLE_BLOCK_INTERRUPTIONS(); SHM_UNPROTECT(); /* Try and cache the script and assume that it is returned from_shared_memory. @@ -2251,7 +2208,7 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) */ if (!persistent_script) { SHM_PROTECT(); - UNBLOCK_ALL_SIGNALS(); + HANDLE_UNBLOCK_INTERRUPTIONS(); return op_array; } if (from_shared_memory) { @@ -2306,7 +2263,7 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) persistent_script->dynamic_members.last_used = ZCG(request_time); SHM_PROTECT(); - UNBLOCK_ALL_SIGNALS(); + HANDLE_UNBLOCK_INTERRUPTIONS(); /* Fetch jit auto globals used in the script before execution */ if (persistent_script->ping_auto_globals_mask) { @@ -2412,13 +2369,13 @@ static zend_string* persistent_zend_resolve_path(const char *filename, size_t fi if (!persistent_script->corrupted) { if (key) { /* add another "key" for the same bucket */ - BLOCK_ALL_SIGNALS(); + HANDLE_BLOCK_INTERRUPTIONS(); SHM_UNPROTECT(); zend_shared_alloc_lock(); zend_accel_add_key(key, key_length, bucket); zend_shared_alloc_unlock(); SHM_PROTECT(); - UNBLOCK_ALL_SIGNALS(); + HANDLE_UNBLOCK_INTERRUPTIONS(); } else { ZCG(key_len) = 0; } @@ -2515,7 +2472,7 @@ int accel_activate(INIT_FUNC_ARGS) } #endif - BLOCK_ALL_SIGNALS(); + HANDLE_BLOCK_INTERRUPTIONS(); SHM_UNPROTECT(); if (ZCG(counted)) { @@ -2574,7 +2531,7 @@ int accel_activate(INIT_FUNC_ARGS) ZCG(accelerator_enabled) = ZCSG(accelerator_enabled); SHM_PROTECT(); - UNBLOCK_ALL_SIGNALS(); + HANDLE_UNBLOCK_INTERRUPTIONS(); if (ZCG(accelerator_enabled) && ZCSG(last_restart_time) != ZCG(last_restart_time)) { /* SHM was reinitialized. */ @@ -3001,10 +2958,6 @@ static int accel_startup(zend_extension *extension) } #endif -#ifdef HAVE_SIGPROCMASK - sigfillset(&mask_all_signals); -#endif - /* no supported SAPI found - disable acceleration and stop initialization */ if (accel_find_sapi() == FAILURE) { accel_startup_ok = 0; @@ -3277,7 +3230,7 @@ void zend_accel_schedule_restart(zend_accel_restart_reason reason) zend_accel_error(ACCEL_LOG_DEBUG, "Restart Scheduled! Reason: %s", zend_accel_restart_reason_text[reason]); - BLOCK_ALL_SIGNALS(); + HANDLE_BLOCK_INTERRUPTIONS(); SHM_UNPROTECT(); ZCSG(restart_pending) = 1; ZCSG(restart_reason) = reason; @@ -3290,7 +3243,7 @@ void zend_accel_schedule_restart(zend_accel_restart_reason reason) ZCSG(force_restart_time) = 0; } SHM_PROTECT(); - UNBLOCK_ALL_SIGNALS(); + HANDLE_UNBLOCK_INTERRUPTIONS(); } /* this is needed because on WIN32 lock is not decreased unless ZCG(counted) is set */ From 6fa3535e49dd2ee25c1d8b4c8a2ba3ca144775a9 Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Tue, 19 May 2020 16:03:45 +0200 Subject: [PATCH 08/11] Remove unnecessary #include zend.h includes zend_signal.h, which includes signal.h. So we don't need to repeat this #include so many times. --- Zend/zend_alloc.c | 1 - Zend/zend_execute.c | 1 - Zend/zend_execute_API.c | 1 - ext/imap/php_imap.c | 1 - ext/mysqli/mysqli.c | 2 -- ext/mysqli/mysqli_api.c | 2 -- ext/mysqli/mysqli_driver.c | 2 -- ext/mysqli/mysqli_exception.c | 2 -- ext/mysqli/mysqli_nonapi.c | 2 -- ext/mysqli/mysqli_prop.c | 2 -- ext/mysqli/mysqli_result_iterator.c | 2 -- ext/mysqli/mysqli_warning.c | 2 -- ext/opcache/ZendAccelerator.c | 1 - ext/opcache/shared_alloc_shm.c | 1 - ext/pcntl/php_signal.h | 3 ++- ext/posix/posix.c | 1 - ext/standard/exec.c | 2 -- ext/standard/mail.c | 4 ---- ext/standard/proc_open.c | 1 - main/main.c | 1 - sapi/cgi/cgi_main.c | 2 -- sapi/cli/php_cli_server.c | 1 - sapi/fpm/fpm/fpm_main.c | 2 -- sapi/litespeed/lsapi_main.c | 1 - sapi/litespeed/lsapilib.c | 1 - sapi/litespeed/lscriu.c | 1 - 26 files changed, 2 insertions(+), 40 deletions(-) diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index 753a8b830d4e..8ff64a4dce1a 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -57,7 +57,6 @@ #include "zend_operators.h" #include "zend_multiply.h" #include "zend_bitset.h" -#include #ifdef HAVE_UNISTD_H # include diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index f30236362122..4469b7c0b029 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -21,7 +21,6 @@ #define ZEND_INTENSIVE_DEBUGGING 0 #include -#include #include "zend.h" #include "zend_compile.h" diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 148b502a8f1b..658d2eb762df 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -19,7 +19,6 @@ */ #include -#include #include "zend.h" #include "zend_compile.h" diff --git a/ext/imap/php_imap.c b/ext/imap/php_imap.c index ccdf34047dc0..09f93b414bbb 100644 --- a/ext/imap/php_imap.c +++ b/ext/imap/php_imap.c @@ -49,7 +49,6 @@ #include #include #include -#include #ifdef PHP_WIN32 #include diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c index eb3c79b7985a..82d6161a8e46 100644 --- a/ext/mysqli/mysqli.c +++ b/ext/mysqli/mysqli.c @@ -20,8 +20,6 @@ #include "config.h" #endif -#include - #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index b364feec4b06..fcdab21a8d12 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -20,8 +20,6 @@ #include "config.h" #endif -#include - #include "php.h" #include "php_ini.h" #include "php_globals.h" diff --git a/ext/mysqli/mysqli_driver.c b/ext/mysqli/mysqli_driver.c index 6bcf5902df58..7362b5d34416 100644 --- a/ext/mysqli/mysqli_driver.c +++ b/ext/mysqli/mysqli_driver.c @@ -18,8 +18,6 @@ #include "config.h" #endif -#include - #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" diff --git a/ext/mysqli/mysqli_exception.c b/ext/mysqli/mysqli_exception.c index d8a8d4dad149..467dda4d5031 100644 --- a/ext/mysqli/mysqli_exception.c +++ b/ext/mysqli/mysqli_exception.c @@ -18,8 +18,6 @@ #include "config.h" #endif -#include - #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c index 5f3114e9df4a..8af0f0f965e4 100644 --- a/ext/mysqli/mysqli_nonapi.c +++ b/ext/mysqli/mysqli_nonapi.c @@ -20,8 +20,6 @@ #include "config.h" #endif -#include - #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" diff --git a/ext/mysqli/mysqli_prop.c b/ext/mysqli/mysqli_prop.c index 2ee059c7563d..33909935cf2d 100644 --- a/ext/mysqli/mysqli_prop.c +++ b/ext/mysqli/mysqli_prop.c @@ -19,8 +19,6 @@ #include "config.h" #endif -#include - #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" diff --git a/ext/mysqli/mysqli_result_iterator.c b/ext/mysqli/mysqli_result_iterator.c index df36a840e41f..d140489bb9ba 100644 --- a/ext/mysqli/mysqli_result_iterator.c +++ b/ext/mysqli/mysqli_result_iterator.c @@ -20,8 +20,6 @@ #include "config.h" #endif -#include - #include "php.h" #include "php_ini.h" #include "php_mysqli_structs.h" diff --git a/ext/mysqli/mysqli_warning.c b/ext/mysqli/mysqli_warning.c index 16cb0ebdfb8c..2a0f80b4df48 100644 --- a/ext/mysqli/mysqli_warning.c +++ b/ext/mysqli/mysqli_warning.c @@ -18,8 +18,6 @@ #include "config.h" #endif -#include - #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 62b3f816ba30..b53e10399fa6 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -73,7 +73,6 @@ typedef int gid_t; # include #endif #include -#include #include #ifndef ZEND_WIN32 diff --git a/ext/opcache/shared_alloc_shm.c b/ext/opcache/shared_alloc_shm.c index 29225bef21df..1746dadbd8d7 100644 --- a/ext/opcache/shared_alloc_shm.c +++ b/ext/opcache/shared_alloc_shm.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include diff --git a/ext/pcntl/php_signal.h b/ext/pcntl/php_signal.h index 4bff5b14b795..52c5f5e427b3 100644 --- a/ext/pcntl/php_signal.h +++ b/ext/pcntl/php_signal.h @@ -14,10 +14,11 @@ +----------------------------------------------------------------------+ */ -#include #ifndef PHP_SIGNAL_H #define PHP_SIGNAL_H +#include + #ifdef HAVE_STRUCT_SIGINFO_T typedef void Sigfunc(int, siginfo_t*, void*); #else diff --git a/ext/posix/posix.c b/ext/posix/posix.c index 090f47a79536..4875e9601a09 100644 --- a/ext/posix/posix.c +++ b/ext/posix/posix.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include diff --git a/ext/standard/exec.c b/ext/standard/exec.c index 9935e2b34c88..7363dd46ef00 100644 --- a/ext/standard/exec.c +++ b/ext/standard/exec.c @@ -30,8 +30,6 @@ #include #endif -#include - #if HAVE_SYS_TYPES_H #include #endif diff --git a/ext/standard/mail.c b/ext/standard/mail.c index 096f432c9a20..1ffbbd983c78 100644 --- a/ext/standard/mail.c +++ b/ext/standard/mail.c @@ -32,10 +32,6 @@ #include #endif -#if PHP_SIGCHILD -#include -#endif - #include "php_syslog.h" #include "php_mail.h" #include "php_ini.h" diff --git a/ext/standard/proc_open.c b/ext/standard/proc_open.c index e463e2515718..3ea2e32c3e62 100644 --- a/ext/standard/proc_open.c +++ b/ext/standard/proc_open.c @@ -17,7 +17,6 @@ #include "php.h" #include #include -#include #include "php_string.h" #include "ext/standard/head.h" #include "ext/standard/basic_functions.h" diff --git a/main/main.c b/main/main.c index af4fc1c681be..5940de6eae64 100644 --- a/main/main.c +++ b/main/main.c @@ -38,7 +38,6 @@ #include #endif -#include #include #include "zend.h" #include "zend_types.h" diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c index 8b65da447860..8f24ea8c87a7 100644 --- a/sapi/cgi/cgi_main.c +++ b/sapi/cgi/cgi_main.c @@ -43,8 +43,6 @@ # include #endif -#include - #include #if HAVE_SYS_TYPES_H diff --git a/sapi/cli/php_cli_server.c b/sapi/cli/php_cli_server.c index 86d8f9f5e1eb..209b5de83864 100644 --- a/sapi/cli/php_cli_server.c +++ b/sapi/cli/php_cli_server.c @@ -42,7 +42,6 @@ #include #endif -#include #include #if HAVE_DLFCN_H diff --git a/sapi/fpm/fpm/fpm_main.c b/sapi/fpm/fpm/fpm_main.c index 79d1f45208eb..34ccfb4efdb5 100644 --- a/sapi/fpm/fpm/fpm_main.c +++ b/sapi/fpm/fpm/fpm_main.c @@ -41,8 +41,6 @@ # include #endif -#include - #include #ifdef HAVE_SYS_TYPES_H diff --git a/sapi/litespeed/lsapi_main.c b/sapi/litespeed/lsapi_main.c index 40c4d4e5f6db..04b641b1761c 100644 --- a/sapi/litespeed/lsapi_main.c +++ b/sapi/litespeed/lsapi_main.c @@ -42,7 +42,6 @@ #endif -#include #include #include #include diff --git a/sapi/litespeed/lsapilib.c b/sapi/litespeed/lsapilib.c index 6cf4cddb9cb1..353fe7fd6f67 100644 --- a/sapi/litespeed/lsapilib.c +++ b/sapi/litespeed/lsapilib.c @@ -54,7 +54,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include -#include #include #include #include diff --git a/sapi/litespeed/lscriu.c b/sapi/litespeed/lscriu.c index f9659b332ab4..4f7a8af469c6 100644 --- a/sapi/litespeed/lscriu.c +++ b/sapi/litespeed/lscriu.c @@ -80,7 +80,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include -#include #include #include #include From 9467fc8244ac45fcb82dc611aff2284f03826e79 Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Sun, 17 May 2020 16:56:05 +0200 Subject: [PATCH 09/11] Remove useless #ifdef's from fpm_signals.c --- sapi/fpm/fpm/fpm_signals.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/sapi/fpm/fpm/fpm_signals.c b/sapi/fpm/fpm/fpm_signals.c index 75e076e07fa2..c0cdd0d66d6c 100644 --- a/sapi/fpm/fpm/fpm_signals.c +++ b/sapi/fpm/fpm/fpm_signals.c @@ -23,42 +23,34 @@ static sigset_t block_sigset; static sigset_t child_block_sigset; const char *fpm_signal_names[NSIG + 1] = { + /* The C standard guarantees at least these 6 signal numbers will be defined in signal.c */ + [SIGABRT] = "SIGABRT", + [SIGFPE] = "SIGFPE", + [SIGILL] = "SIGILL", + [SIGINT] = "SIGINT", + [SIGSEGV] = "SIGSEGV", + [SIGTERM] = "SIGTERM", #ifdef SIGHUP [SIGHUP] = "SIGHUP", #endif -#ifdef SIGINT - [SIGINT] = "SIGINT", -#endif #ifdef SIGQUIT [SIGQUIT] = "SIGQUIT", #endif -#ifdef SIGILL - [SIGILL] = "SIGILL", -#endif #ifdef SIGTRAP [SIGTRAP] = "SIGTRAP", #endif -#ifdef SIGABRT - [SIGABRT] = "SIGABRT", -#endif #ifdef SIGEMT [SIGEMT] = "SIGEMT", #endif #ifdef SIGBUS [SIGBUS] = "SIGBUS", #endif -#ifdef SIGFPE - [SIGFPE] = "SIGFPE", -#endif #ifdef SIGKILL [SIGKILL] = "SIGKILL", #endif #ifdef SIGUSR1 [SIGUSR1] = "SIGUSR1", #endif -#ifdef SIGSEGV - [SIGSEGV] = "SIGSEGV", -#endif #ifdef SIGUSR2 [SIGUSR2] = "SIGUSR2", #endif @@ -68,9 +60,6 @@ const char *fpm_signal_names[NSIG + 1] = { #ifdef SIGALRM [SIGALRM] = "SIGALRM", #endif -#ifdef SIGTERM - [SIGTERM] = "SIGTERM", -#endif #ifdef SIGCHLD [SIGCHLD] = "SIGCHLD", #endif From 9f6d44e395c7a8795b1bb68cfd505aa9b99c9317 Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Fri, 22 May 2020 20:27:31 +0200 Subject: [PATCH 10/11] Move blocking/unblocking of signals out of hot path in ZendAccelerator.c This code courtesy of Nikita Popov. Apparently, it vastly reduces the performance load of sigprocmask syscalls caused by removal of Zend signal handling. --- ext/opcache/ZendAccelerator.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index b53e10399fa6..b74084861a51 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -2118,7 +2118,6 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) return NULL; } - HANDLE_BLOCK_INTERRUPTIONS(); SHM_UNPROTECT(); /* If script is found then validate_timestamps if option is enabled */ @@ -2167,7 +2166,9 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) /* Check the second level cache */ if (!persistent_script && ZCG(accel_directives).file_cache) { + HANDLE_BLOCK_INTERRUPTIONS(); persistent_script = zend_file_cache_script_load(file_handle); + HANDLE_UNBLOCK_INTERRUPTIONS(); } /* If script was not found or invalidated by validate_timestamps */ @@ -2181,7 +2182,6 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) /* No memory left. Behave like without the Accelerator */ if (ZSMMG(memory_exhausted) || ZCSG(restart_pending)) { SHM_PROTECT(); - HANDLE_UNBLOCK_INTERRUPTIONS(); if (ZCG(accel_directives).file_cache) { return file_cache_compile_file(file_handle, type); } @@ -2189,9 +2189,7 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) } SHM_PROTECT(); - HANDLE_UNBLOCK_INTERRUPTIONS(); persistent_script = opcache_compile_file(file_handle, type, key, &op_array); - HANDLE_BLOCK_INTERRUPTIONS(); SHM_UNPROTECT(); /* Try and cache the script and assume that it is returned from_shared_memory. @@ -2199,7 +2197,9 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) */ from_shared_memory = 0; if (persistent_script) { + HANDLE_BLOCK_INTERRUPTIONS(); persistent_script = cache_script_in_shared_memory(persistent_script, key, key ? key_length : 0, &from_shared_memory); + HANDLE_UNBLOCK_INTERRUPTIONS(); } /* Caching is disabled, returning op_array; @@ -2207,7 +2207,6 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) */ if (!persistent_script) { SHM_PROTECT(); - HANDLE_UNBLOCK_INTERRUPTIONS(); return op_array; } if (from_shared_memory) { @@ -2262,10 +2261,9 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) persistent_script->dynamic_members.last_used = ZCG(request_time); SHM_PROTECT(); - HANDLE_UNBLOCK_INTERRUPTIONS(); - /* Fetch jit auto globals used in the script before execution */ - if (persistent_script->ping_auto_globals_mask) { + /* Fetch jit auto globals used in the script before execution */ + if (persistent_script->ping_auto_globals_mask) { zend_accel_set_auto_globals(persistent_script->ping_auto_globals_mask); } From df45e01ce740becf77e773f52c04a60debf2eaa5 Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Fri, 22 May 2020 20:37:14 +0200 Subject: [PATCH 11/11] Avoid recursive use of signal blocking macros in ZendAccelerator.c --- Zend/zend.c | 11 +++++++++-- Zend/zend_signal.h | 3 +++ ext/opcache/ZendAccelerator.c | 9 +++++++-- ext/opcache/zend_accelerator_module.c | 2 ++ 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/Zend/zend.c b/Zend/zend.c index 4c98ee396a9f..fa27d9fcfbbf 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -78,8 +78,15 @@ ZEND_API void zend_debug_mask_signals() } ZEND_API void zend_debug_unmask_signals() { - if (--_signals_masked) - zend_error_noreturn(E_ERROR, "Cannot nest ZEND_SIGNAL_BLOCK_INTERRUPTIONS; it is not re-entrant"); + if (--_signals_masked) { + zend_error_noreturn(E_ERROR, "Cannot nest HANDLE_BLOCK_INTERRUPTIONS; it is not re-entrant"); + } +} +ZEND_API void zend_debug_ensure_signals_masked() +{ + if (!_signals_masked) { + zend_error_noreturn(E_ERROR, "Must block signals using HANDLE_BLOCK_INTERRUPTIONS"); + } } # endif #endif diff --git a/Zend/zend_signal.h b/Zend/zend_signal.h index b66a9c582c39..bb3ab4cc4f42 100644 --- a/Zend/zend_signal.h +++ b/Zend/zend_signal.h @@ -26,9 +26,11 @@ extern sigset_t mask_all_signals; # if ZEND_DEBUG ZEND_API void zend_debug_mask_signals(); ZEND_API void zend_debug_unmask_signals(); +ZEND_API void zend_debug_ensure_signals_masked(); # else # define zend_debug_mask_signals() do {} while (0) # define zend_debug_unmask_signals() do {} while (0) +# define zend_debug_ensure_signals_masked() do {} while (0) # endif # define ZEND_SIGNAL_BLOCK_INTERRUPTIONS() \ @@ -55,6 +57,7 @@ ZEND_API void zend_debug_unmask_signals(); # define ZEND_SIGNAL_BLOCK_INTERRUPTIONS() do {} while(0) # define ZEND_SIGNAL_UNBLOCK_INTERRUPTIONS() do {} while(0) +# define zend_debug_ensure_signals_masked() do {} while(0) #endif /* HAVE_SIGPROCMASK */ #endif /* ZEND_SIGNAL_H */ diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index b74084861a51..952b1d3909f6 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -2131,7 +2131,9 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) if (ZSMMG(memory_exhausted)) { zend_accel_restart_reason reason = zend_accel_hash_is_full(&ZCSG(hash)) ? ACCEL_RESTART_HASH : ACCEL_RESTART_OOM; + HANDLE_BLOCK_INTERRUPTIONS(); zend_accel_schedule_restart_if_necessary(reason); + HANDLE_UNBLOCK_INTERRUPTIONS(); } } zend_shared_alloc_unlock(); @@ -2156,7 +2158,9 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) if (ZSMMG(memory_exhausted)) { zend_accel_restart_reason reason = zend_accel_hash_is_full(&ZCSG(hash)) ? ACCEL_RESTART_HASH : ACCEL_RESTART_OOM; + HANDLE_BLOCK_INTERRUPTIONS(); zend_accel_schedule_restart_if_necessary(reason); + HANDLE_UNBLOCK_INTERRUPTIONS(); } } zend_shared_alloc_unlock(); @@ -3227,7 +3231,9 @@ void zend_accel_schedule_restart(zend_accel_restart_reason reason) zend_accel_error(ACCEL_LOG_DEBUG, "Restart Scheduled! Reason: %s", zend_accel_restart_reason_text[reason]); - HANDLE_BLOCK_INTERRUPTIONS(); + /* This function must be called with signals blocked */ + zend_debug_ensure_signals_masked(); + SHM_UNPROTECT(); ZCSG(restart_pending) = 1; ZCSG(restart_reason) = reason; @@ -3240,7 +3246,6 @@ void zend_accel_schedule_restart(zend_accel_restart_reason reason) ZCSG(force_restart_time) = 0; } SHM_PROTECT(); - HANDLE_UNBLOCK_INTERRUPTIONS(); } /* this is needed because on WIN32 lock is not decreased unless ZCG(counted) is set */ diff --git a/ext/opcache/zend_accelerator_module.c b/ext/opcache/zend_accelerator_module.c index 7ff085c05952..ee02fb868ad0 100644 --- a/ext/opcache/zend_accelerator_module.c +++ b/ext/opcache/zend_accelerator_module.c @@ -851,9 +851,11 @@ ZEND_FUNCTION(opcache_reset) } /* exclusive lock */ + HANDLE_BLOCK_INTERRUPTIONS(); zend_shared_alloc_lock(); zend_accel_schedule_restart(ACCEL_RESTART_USER); zend_shared_alloc_unlock(); + HANDLE_UNBLOCK_INTERRUPTIONS(); RETURN_TRUE; }