On 3/5/26 3:06 PM, Daniel Villeneuve wrote:
On 3/5/26 12:40, Chet Ramey wrote:It depends. Do you have a specific reproducer that works outside of reboot?Thanks for hinting this could be done without reboot. Here it is.
I tried for several hours to reproduce your results on Fedora 42 with the latest devel branch code (otherwise, why bother looking for a fix?) and I simply cannot. I mixed the signal delivery order with /usr/bin/kill, added a short timeout, and tried several other variants to reproduce the issue. The closest I got was sending SIGHUP first, then delaying the SIGTERM. That sometimes ran the loop in the exit trap once before the SIGTERM was delivered (whether running the exit trap after the sleep terminated or after the shell received the SIGHUP), but then the SIGTERM was delivered, the SIGTERM trap ran, and the shell exited. I added some tracing annotations to the code so we can see what's going on, and sent the signals to the script according to your recipe: $ ./bash foo.sh + trap 'errtrap || true' EXIT + trap 'termtrap || true; kill -TERM $$' TERM + sleep infinity Normal script start here. TRACE: pid 15612: wait_for: calling CHECK_TERMSIG before waitchld for 15613 TRACE: pid 15612: waitchld: calling CHECK_TERMSIG before waitpid for 15613 The shell checks for terminating signals before calling waitpid() on the sleep process (15613). Nothing yet. TRACE: pid 15612: termsig_sighandler: sig = 1 handling_termsig = 0If the SIGHUP comes first (and it will -- with a 0 timeout, you'll get the lower-numbered signal delivered first, and terminating signals are handled
before trapped signals, since traps are run at command boundaries), the shell calls the signal handler and notes that we got a terminating signal (1). TRACE: pid 15612: trap_handler: sig = 15 The SIGTERM arrives, and the signal handler for trapped signals is called. It notes there is a pending trap for SIGTERM.TRACE: pid 15612: waitchld: calling CHECK_TERMSIG after waitpid for 15613 (return -1)
waitpid() gets interrupted by the SIGHUP/SIGTERM combo and returns -1/ EINTR. Bash checks for terminating signals after calling waitpid(). TRACE: pid 15612: termsig_handler: sig = 1 handling_termsig = 0 The shell notes there is a pending terminating signal and calls the cleanup handler. We do it this way to avoid running a lot of code in a signal handler, and so we can use signal-unsafe functions like malloc(). TRACE: pid 15612: termsig_handler: sig = 1: calling run_exit_trap The shell runs the EXIT trap before terminating due to the fatal SIGHUP. Note the SIGTERM trap hasn't run yet, since fatal signals take precedence and we haven't hit a command boundary. TRACE: pid 15612: run_exit_trap: running_trap = 0 We run the exit trap, and note that we have a pending trap to execute before running a command (we are at a command boundary). We note that we are not running the EXIT trap from a trap handler; it's useful to know that. TRACE: pid 15612: run_pending_traps: running_trap = 1 pending_trap = 15 We note that we are about to run a trap (15) while another trap handler (0 -- running_trap is 1 greater than the signal number) is executing. We allow this; people want to be able to run traps from trap handlers.foo.sh: DEBUG warning: run_pending_traps: 15612: recursive invocation while running trap for signal 0
And warn about it, if the shell's release status isn't `release'.
TRACE: pid 15612: run_pending_traps: running trap for signal 15
Now we run the SIGTERM trap.
+++ termtrap
+++ trap - EXIT TERM
This sets the SIGTERM signal handler back to termsig_sighandler.
+++ echo termtrap
termtrap
+++ return 0
+++ kill -TERM 15612
The trap action sends SIGTERM to the shell process.
TRACE: pid 15612: termsig_sighandler: sig = 15 handling_termsig = 1
The shell gets the SIGTERM, notices that it's already handling a
terminating signal (the SIGHUP), and kills itself with SIGTERM
immediately.
Terminated
And the shell process terminates due to SIGTERM.
Maybe you can help me think through what might be going on in your test.
Chet
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU [email protected] http://tiswww.cwru.edu/~chet/
OpenPGP_signature.asc
Description: OpenPGP digital signature
