php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #73783 SIG_IGN doesn't work when Zend Signals is enabled
Submitted: 2016-12-19 10:25 UTC Modified: 2016-12-29 20:17 UTC
From: zorg at razza dot org Assigned:
Status: Closed Package: PCNTL related
PHP Version: 7.1.0 OS: Ubuntu 16.04.1 LTS
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: zorg at razza dot org
New email:
PHP Version: OS:

 

 [2016-12-19 10:25 UTC] zorg at razza dot org
Description:
------------
The use of pcntl_signal(SIGCHLD, SIG_IGN) breaks sleep(). In 7.0 the below script would sleep for 60 seconds then exit, in 7.1 the script does not sleep at all.

Test script:
---------------
pcntl_signal(SIGCHLD, SIG_IGN);
sleep(60);
exit('Done');

Expected result:
----------------
Sleep for 60 seconds, print 'Done' and exit.

Actual result:
--------------
Instantly prints 'Done' and exist.

Patches

Pull Requests

Pull requests:

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-12-19 10:30 UTC] 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.
 [2016-12-19 14:00 UTC] cmb@php.net
-Package: *General Issues +Package: PCNTL related
 [2016-12-19 20:54 UTC] 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-20 08:15 UTC] 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-20 15:41 UTC] 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-29 20:17 UTC] nikic@php.net
-Summary: pcntl_signal() issue +Summary: SIG_IGN doesn't work when Zend Signals is enabled
 [2016-12-29 20:19 UTC] nikic@php.net
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
 [2016-12-29 20:19 UTC] nikic@php.net
-Status: Open +Status: Closed
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Wed Sep 11 17:02:22 2024 UTC