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 = 0

If 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/

Attachment: OpenPGP_signature.asc
Description: OpenPGP digital signature

Reply via email to