Bug #73783 [Opn->Csd]: SIG_IGN doesn't work when Zend Signals is enabled
| From: | nikic@php.net | Date: | Thu, 29 Dec 2016 20:19:10 +0000 |
| Subject: | Bug #73783 [Opn->Csd]: SIG_IGN doesn't work when Zend Signals is enabled | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-206232@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=73783&edit=1
ID: 73783
Updated by: nikic@php.net
Reported by: zorg at razza dot org
Summary: SIG_IGN doesn't work when Zend Signals is enabled
-Status: Open
+Status: Closed
Type: Bug
Package: PCNTL related
Operating System: Ubuntu 16.04.1 LTS
PHP Version: 7.1.0
Block user comment: N
Private report: N
New Comment:
Automatic comment on behalf of dave@mudsite.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=b09c2f899ebc14029d0936d770cced10b607f84b
Log: Fixed bug #73783
Previous Comments:
------------------------------------------------------------------------
[2016-12-25 20:50:08] dave at mudsite dot com
Related To: Bug #71437
------------------------------------------------------------------------
[2016-12-20 15:41:17] dave at mudsite dot com
I would assume as much, I wasn't directly able to replicate the <defunct> process. I
tried on both my Debian setup & MacOS 10.12, which both lack the <defunct> but do both
sleep correctly with the fix in place.
The output I get with PHP 7.1, and my fix are as follows:
dwalker@linux:~/src/php PHP-7.1 ⺠time sapi/cli/php e.php && ps aux | grep defunc
Parent
Child Dying
After Sleep
real 0m0.022s
user 0m0.004s
sys 0m0.016s
dwalker 24037 0.0 0.0 12784 940 pts/3 S+ 08:38 0:00 grep --color=auto defunc
dwalker@linux:~/src/php fix-73783 ⺠time sapi/cli/php e.php && ps aux | grep defunc
Parent
Child Dying
After Sleep
real 0m10.015s
user 0m0.012s
sys 0m0.004s
dwalker 16683 0.0 0.0 12784 900 pts/3 S+ 08:37 0:00 grep --color=auto defunc
------------------------------------------------------------------------
[2016-12-20 08:15:22] zorg at razza dot org
Would this also fix the issue where pcntl_signal(SIGCHLD, SIG_IGN) no longer stops <defunct>
threads from remaining until the main process has ended? In 7.0 threads would exit cleanly, but
since upgrading to 7.1 they all sit as <defunct> now.
------------------------------------------------------------------------
[2016-12-19 20:54:16] dave at mudsite dot com
This bug exists because ZEND_SIGNALS was defaulted to "yes" with PHP 7.1. The problem
with this is that sleep() will sleep for the number of seconds, OR, is interrupted by a signal that
is not ignored.
With your test script with pcntl_signal(SIGCHLD, SIG_IGN), you're instructing PHP to ignore the
end of a child. However, ZEND_SIGNALS, zend_sigaction() sets the set handler into the
SIGG(handlers), but, will set the actual signal handler to zend_signal_handler_defer, which is not
SIG_IGN. As such, during the sleeping, when a SIGCHLD is raised, sleep bails because it is not
"ignored" at the system level, and ends up calling zend_signal_handler_defer which will
not process the signal.
I believe a safe fix would be to in zend_sigaction, only set the defer handler IF the incoming
sigact's handler is not SIG_IGN. Will make a PR and see if it's acceptable or not.
------------------------------------------------------------------------
[2016-12-19 10:30:51] zorg at razza dot org
Sorry, the test script is incorrect. It should be:
pcntl_signal(SIGCHLD, SIG_IGN);
$pid = @pcntl_fork();
if ($pid == -1)
{
exit(pcntl_get_last_error() . ': ' . pcntl_strerror(pcntl_get_last_error()));
}
elseif ($pid == 0)
{
exit();
}
sleep(60);
exit("Done");
This also creates a <defunct> process when pcntl_signal(SIGCHLD, SIG_IGN) should have removed
it.
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=73783
--
Edit this bug report at https://bugs.php.net/bug.php?id=73783&edit=1