Bug #55614 [Fbk->Asn]: pcntl_signal() + fgetc() is not allowing me to break with CTRL+C
| From: | i3367890 at gmail dot com | Date: | Thu, 08 Jul 2021 06:21:26 +0000 |
| Subject: | Bug #55614 [Fbk->Asn]: pcntl_signal() + fgetc() is not allowing me to break with CTRL+C | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-234892@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=55614&edit=1
ID: 55614
User updated by: i3367890 at gmail dot com
Reported by: i3367890 at gmail dot com
Summary: pcntl_signal() + fgetc() is not allowing me to break
with CTRL+C
-Status: Feedback
+Status: Assigned
Type: Bug
Package: PCNTL related
-Operating System: (Arch) Linux
+Operating System: (Arch, Debian) Linux
-PHP Version: 5.3.8
+PHP Version: 5.3.8 - 8.0.7
Assigned To: cmb
Block user comment: N
Private report: N
New Comment:
Wow, I completely forgot about posting this. Thanks for following up.
Unfortunately it does still seem to be hanging around.
$ php --version
PHP 8.0.7 (cli) (built: Jun 4 2021 23:17:30) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.7, Copyright (c) Zend Technologies
with Zend OPcache v8.0.7, Copyright (c), by Zend Technologies
(This is from deb.sury.org. I'm on Debian now.)
$ php -r "declare(ticks = 1); function quit() { print \"X\\n\"; die; }
pcntl_signal(SIGINT, \"quit\"); fgetc(STDIN);"
^C^C^C^C^C^C^\Quit
$ _
Continuous ^C^C^C still simply retries forever:
PHP tty | strace tty
| ...
| rt_sigprocmask(SIG_UNBLOCK, [INT], NULL, 8) = 0
| read(0, 0x7fd24947f000, 8192) = ? ERESTARTSYS (To be restarted if SA_RESTART
is set)
^C ---------------^
| --- SIGINT {si_signo=SIGINT, si_code=SI_KERNEL} ---
| rt_sigreturn({mask=[]}) = 0
| read(0, 0x7fd24947f000, 8192) = ? ERESTARTSYS (To be restarted if SA_RESTART
is set)
^C ---------------^
| --- SIGINT {si_signo=SIGINT, si_code=SI_KERNEL} ---
| rt_sigreturn({mask=[]}) = 0
| read(0, 0x7fd24947f000, 8192) = ? ERESTARTSYS (To be restarted if SA_RESTART
is set)
^C ---------------^
| --- SIGINT {si_signo=SIGINT, si_code=SI_KERNEL} ---
| rt_sigreturn({mask=[]}) = 0
| read(0, "x\n", 8192) = 2
'x' + ------------^
<Return> | rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], [], 8) = 0
Exit-> | write(1, "X\n", 2) = 2
| rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], ~[KILL STOP RTMIN RT_1], 8) = 0
| rt_sigprocmask(SIG_SETMASK, ~[KILL STOP RTMIN RT_1], NULL, 8) = 0
| rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
| close(2) = 0
| close(1) = 0
| close(0) = 0
| munmap(..., ...) = 0
| ...
(NB, the note about
stty cbreak at the end of the 2nd comment is somewhat orthogonal to
this bug; inputting any text then pressing Return IMO suffices to demonstrate that normal input is
consumed correctly.)
Setting restart_signals to false still consumes one ^C before responding correctly to the second:
$ strace -o /dev/pts/26 php -r "declare(ticks = 1); function quit() { print \"X\\n\";
die; } pcntl_signal(SIGINT, \"quit\", 0); fgetc(STDIN);"
^C^CX
PHP tty | strace tty
| rt_sigprocmask(SIG_UNBLOCK, [INT], NULL, 8) = 0
| read(0, 0x7f66fb47e000, 8192) = ? ERESTARTSYS (To be restarted if SA_RESTART
is set)
^C 1 -------------^
| --- SIGINT {si_signo=SIGINT, si_code=SI_KERNEL} ---
| rt_sigreturn({mask=[]}) = -1 EINTR (Interrupted system call)
| read(0, 0x7f66fb47e000, 8192) = ? ERESTARTSYS (To be restarted if SA_RESTART
is set)
^C 2 -------------^
| --- SIGINT {si_signo=SIGINT, si_code=SI_KERNEL} ---
| rt_sigreturn({mask=[]}) = -1 EINTR (Interrupted system call)
| rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], [], 8) = 0
Exit-> | write(1, "X\n", 2) = 2
| rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], ~[KILL STOP RTMIN RT_1], 8) = 0
| rt_sigprocmask(SIG_SETMASK, ~[KILL STOP RTMIN RT_1], NULL, 8) = 0
| rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
| close(2) = 0
| close(1) = 0
| close(0) = 0
| munmap(0x7f66f7cb7000, 29808) = 0
| munmap(0x7f66f7cbf000, 16592) = 0
Previous Comments:
------------------------------------------------------------------------
[2021-07-06 16:18:40] cmb@php.net
Is this still an issue with any of the actively supported PHP
versions[1]?
[1] <https://www.php.net/supported-versions.php>
------------------------------------------------------------------------
[2011-09-06 03:24:59] i3367890 at gmail dot com
I forgot to mention something!
In the first script pressing a key (any key) causes PHP to shut down properly.
Here's what it looks like:
My console | strace console
| (....)
| rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
| read(0, 0x8b825f8, 8192) = ? ERESTARTSYS (To be restarted)
^C ---------------^
| --- SIGINT (Interrupt) @ 0 (0) ---
I | sigreturn() = ? (mask now [])
pressed | read(0, "d", 8192) = 1
"d" -------------^
| rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], [], 8) = 0
! --> | write(1, "X\n", 2) = 2
| rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], ~[KILL STOP RTMIN RT_1],
8) = 0
| rt_sigprocmask(SIG_SETMASK, ~[KILL STOP RTMIN RT_1], NULL, 8) = 0
| close(2) = 0
My console | strace console
| (....)
=======
NOTE:
=======
If fgetc(STDIN) does not return immediately after a single character - it
doesn't on my system, it waits for a newline - you might need to run "stty
cbreak". When you're done run "stty -cbreak" if you want to switch whatever
cbreak does back off, or just close the terminal.
i336
------------------------------------------------------------------------
[2011-09-06 03:15:08] i3367890 at gmail dot com
Description:
------------
Running the following code at the commandline as demonstrated simply does not
work for me. It gobbles up all presses of ^C and will not quit (^\ ie CTRL+\
produces SIGQUIT and is useful in this situation):
php -r "declare(ticks = 1); function quit() { print \"X\\n\"; die; }
pcntl_signal(SIGINT, \"quit\"); fgetc(STDIN);"
Running the following, on the other hand, works for me just fine.
php -r "declare(ticks = 1); function quit() { print \"X\\n\"; die; }
pcntl_signal(SIGINT, \"quit\"); while(1) { sleep(1); };"
Pressing ^C shuts the script down nicely.
I see no problems with the first code example. It should work, right? Here's
what
strace is saying:
My console | strace console
| (....)
| rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], [], 8) = 0
| rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
| read(0, 0x943e5f4, 8192) = ? ERESTARTSYS (To be restarted)
| --- SIGINT (Interrupt) @ 0 (0) ---
| sigreturn() = ? (mask now [])
| read(0, 0x943e5f4, 8192) = ? ERESTARTSYS (To be restarted)
^C ---------------^
| --- SIGINT (Interrupt) @ 0 (0) ---
| sigreturn() = ? (mask now [])
| read(0, 0x943e5f4, 8192) = ? ERESTARTSYS (To be restarted)
^C ---------------^
| --- SIGINT (Interrupt) @ 0 (0) ---
| sigreturn() = ? (mask now [])
| read(0,
(waiting) ---------^
It gets even more interesting. Setting parameter 3 to pcntl_signal,
restart_signals, to false makes PHP gobble up one ^C *then* quit:
php -r "declare(ticks = 1); function quit() { print \"X\\n\"; die; }
pcntl_signal(SIGINT, \"quit\", 0); fgetc(STDIN);"
Like so:
My console | strace console
| (...)
| rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], [], 8) = 0
| rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
| rt_sigaction(SIGINT, {0x82d8690, ~[RTMIN RT_1], SA_INTERRUPT},
{SIG_DFL, [], 0}, 8) = 0
| rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], [], 8) = 0
| rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
| read(0, 0x9e985f8, 8192) = ? ERESTARTSYS (To be restarted)
^C --------------^
| --- SIGINT (Interrupt) @ 0 (0) ---
| sigreturn() = ? (mask now [])
| read(0, 0x9e985f8, 8192) = ? ERESTARTSYS (To be restarted)
^C --------------^
| --- SIGINT (Interrupt) @ 0 (0) ---
| sigreturn() = ? (mask now [])
| rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], [], 8) = 0
! --> | write(1, "X\n", 2) = 2
| rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], ~[KILL STOP RTMIN RT_1],
8)
= 0
| rt_sigprocmask(SIG_SETMASK, ~[KILL STOP RTMIN RT_1], NULL, 8) = 0
| close(2) = 0
| close(1) = 0
| (...)
As you can see from my exclamation, *the custom quit function is WORKING* in the
second example, just not straight away. PHP seems to be having indigestion with
the restart_syscalls bit...?
I wasn't sure what to put in what boxes since there were multiple scripts and
backtraces (if you could call them such) so I put them all here. Hope that's
okay.
i336
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=55614&edit=1