From: Corinna Vinschen <cori...@vinschen.de> Commit 0b6fbd396ca2f ("* exceptions.cc (_cygtls::interrupt_now): Revert to checking for "spinning" when choosing to defer signal.") introduced a bug in the loop inside the stabilize_sig_stack subroutine:
First, stabilize_sig_stack grabs the stacklock. The _cygtls::incyg flag is then incremented before checking if a signal has to be handled for the current thread. If no signal waits, the code simply jumps out, decrements _cygtls::incyg and returns to the caller, which eventually releases the stacklock. However, if a signal is waiting, stabilize_sig_stack releases the stacklock, calls _cygtls::call_signal_handler(), and returns to the start of the subroutine, trying to grab the lock. After grabbing the lock, it increments _cygtls::incyg... wait... again? The loop does not decrement _cygtls::incyg after _cygtls::call_signal_handler(), which returns with _cygtls::incyg set to 1. So it increments incyg to 2. If no other signal is waiting, stabilize_sig_stack jumps out and decrements _cygtls::incyg to 1. Eventually, setjmp or longjmp both will return to user code with _cygtls::incyg set to 1. This *may* be fixed at some later point when signals arrive, but there will be a time when the application runs in user code with broken signal handling. Fixes: 0b6fbd396ca2f ("* exceptions.cc (_cygtls::interrupt_now): Revert to checking for "spinning" when choosing to defer signal.") Signed-off-by: Corinna Vinschen <cori...@vinschen.de> --- winsup/cygwin/scripts/gendef | 1 + 1 file changed, 1 insertion(+) diff --git a/winsup/cygwin/scripts/gendef b/winsup/cygwin/scripts/gendef index 7e14f69cf71c..377ceb59b2c8 100755 --- a/winsup/cygwin/scripts/gendef +++ b/winsup/cygwin/scripts/gendef @@ -344,6 +344,7 @@ stabilize_sig_stack: movq \$_cygtls.start_offset,%rcx # point to beginning addq %r12,%rcx # of tls block call _ZN7_cygtls19call_signal_handlerEv + decl _cygtls.incyg(%r12) jmp 1b 3: decl _cygtls.incyg(%r12) addq \$0x20,%rsp -- 2.47.0