Hello again,
Here is another analysis that my collegue made on the issue: Bash Compiled for wrong OS? 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: 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 6707 rt_sigprocmask(SIG_BLOCK, NULL, [USR1 CHLD], 8) = 0 6707 rt_sigprocmask(SIG_BLOCK, [INT TERM CHLD], [USR1 CHLD], 8) = 0 6707 clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x76fe9028) = 6725 6707 rt_sigprocmask(SIG_SETMASK, [USR1 CHLD], NULL, 8) = 0 6707 rt_sigprocmask(SIG_BLOCK, [CHLD], [USR1 CHLD], 8) = 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, [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 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 rt_sigprocmask(SIG_BLOCK, [CHLD], [USR1 CHLD], 8) = 0 6707 rt_sigaction(SIGINT, {sa_handler=0x46e15, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x76e90711}, <unfinished ...> 6707 <... rt_sigaction resumed>{sa_handler=0x46e15, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x76e90711}, 8) = 0 6707 wait4(-1, <unfinished ...> 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. 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. According to strace no additional user flags are set when the BASH signal handler is put in place for SIGUSR1. We need to look at bash build options, and possible the signal handling code, and sigprocmask or whatever C API they are using to call sigprocmask().