[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: wait skips signals but first one
From: |
Chet Ramey |
Subject: |
Re: wait skips signals but first one |
Date: |
Sat, 3 Feb 2024 15:25:30 -0500 |
User-agent: |
Mozilla Thunderbird |
On 2/3/24 10:28 AM, Mykyta Dorokhin wrote:
Analysis with strace.
After receiving SIGUSR1, Debian only blocks SIGCHLD, then clears the block:
205295 --- SIGUSR1 {si_signo=SIGUSR1, si_code=SI_USER, si_pid=205327,
si_uid=1040} ---
205295 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
205295 rt_sigaction(SIGINT, {sa_handler=SIG_DFL, sa_mask=[],
sa_flags=SA_RESTORER, sa_restorer=0x7f063bdb5fd0},
{sa_handler=0x5637247940b0, sa_mask=[], sa_flags=SA_RESTORER,
sa_restorer=0x7f063bdb5fd0}, 8) = 0
205295 rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
205295 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 # unblocks all signalas
The above is the correct action.
On our device, it blocks SIGUSR1 as well as SIGCHLD and keeps doing it over
and over again:
One explanation for this is SIGUSR1 being blocked when the shell is
invoked. Another is that sigsetjmp/siglongjmp are either not available
(or configure doesn't think they are) or don't properly save and restore
the signal mask.
6707 --- SIGUSR1 {si_signo=SIGUSR1, si_code=SI_USER, si_pid=6724,
si_uid=0} ---
6707 rt_sigprocmask(SIG_BLOCK, [CHLD], [USR1 CHLD], 8) = 0
6707 rt_sigprocmask(SIG_SETMASK, [USR1 CHLD], NULL, 8) = 0
6707 rt_sigprocmask(SIG_BLOCK, NULL, [USR1 CHLD], 8) = 0
6707 write(1, ">>> TRAPPED USR1 <<<\n", 21) = 21
6707 rt_sigprocmask(SIG_BLOCK, [CHLD], [USR1 CHLD], 8) = 0
6707 rt_sigprocmask(SIG_SETMASK, [USR1 CHLD], NULL, 8) = 0
6707 rt_sigprocmask(SIG_BLOCK, [CHLD], [USR1 CHLD], 8) = 0
6707 rt_sigprocmask(SIG_SETMASK, [USR1 CHLD], NULL, 8) = 0
6707 write(1, "Iteration\n", 10) = 10
On modern systems, the OS blocks the signal that is caught during signal
handling, and unblocks so that signal handlers are not called recursively.
The exception to this is if SA_NODEFER is set. On some very old UNIX
systems you had to block the signal yourself, and there was a small window
where things could go wrong. I suspect BASH probably has a build option to
allow blocking signals in handlers for compatibility with other systems,
and is not being built correctly for Linux.
Bash does have an autoconf test for this, but it didn't change as part
of this push. You can check what MUST_REINSTALL_SIGHANDLERS is set to
in config.h, but I suspect it won't be different.
And `not being built correctly for Linux' would mean your Debian and my
Red Hat tests would fail.
I suspect on those very old
systems the signal was automatically unblocked on return, but is not done
here, because the POSIX sigprocmask is called, which requires calling it
again to unblock the signal in Linux. And since wait is restarted, it
never is unblocked.
If you mean wait(2), it doesn't get restarted. waitpid(2) will return
-1/EINTR since it received a caught signal.
According to strace no additional user flags are set when the BASH signal
handler is put in place for SIGUSR1.
Correct, the trap signal handler doesn't assume that system calls are
restarted.
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU chet@case.edu http://tiswww.cwru.edu/~chet/
OpenPGP_signature.asc
Description: OpenPGP digital signature