Hi,

We will probably have to introduce --enable-zend-signals configure switch and disable zend signals by default. Or we will stuck with 5.4 release forever.

Thanks. Dmitry.
--- Begin Message ---
Hi Arnaud and Lucas,

I can confirm the problem. Just start Apache with mod_php, generate some load (e.g. ab -t 120 http://.../hello.php), then run 'apachectl restart' for few times, then 'apachectl stop'. You will see warning and error messages in error_log

[warn] child process 15317 still did not exit, sending a SIGTERM

[error] child process 15317 still did not exit, sending a SIGKILL

The problem goes away if I compile php without ZEND_SIGNALS.

I tried to analyze and debug zend_signal.c and found very wired behavior.

On first request zend_signal_activate() sets its own signal handler for SIGHUP and stores the original handler in SIGG(handlers)[SIGHUP-1].handler, but on second request the same zend_signal_activate() overwrites the original signal handler by handler from parent process.

zend_signal.c:284

memcpy(&SIGG(handlers), &global_orig_handlers, sizeof(global_orig_handlers));

As result the original signal handler for SIGHUP is never called.
Even worse after restart and two request SIGG(handlers)[SIGHUP-1].handler becomes SIG_IGN and SIGHUP is ignored at all.

I'm not going to fix it myself.

Thanks. Dmitry.

On 02/08/2012 08:58 PM, Yoram bar-haim wrote:
Hello all.
After intensive debugging of PHP restart issues (child processes don't go down
fast enough for apache, so SIGTERM and sometimes SIGKILL are sent), I found
out the following problem in PHP signal handling mechanism.

on startup (zend_signal_startup()), :
        PHP copies the current sigactions for all signals into
global_orig_handlers.
on activate (zend_signal_activate()) :
        global_orig_handlers are copied int zend_global_handlers.
        zend_signal_handler_defer is registered as signal handler (also in
zend_global_handlers).

Please note that zend_signal_startup() happens *before* set_signals() in
apache startup.

his logic works fine, unless SIGHUP is called after zend_signal_activate() was
started but before zend_signal_register() finished to register handler.
on that situation, the default (SIG_IGN) will found in
zend_global_handlers.handlers[0].handler by zend_signal_handler and the signal
will be ignored.
as result, child shutdown will not occur on SIGHUP but only later on SIGTERM.

I'm still trying to find a fix for this problem, but it will be better if Dmitry
ans Stas  will also take a look.



--- End Message ---
-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to