[newlib-cygwin/cygwin-3_5-branch] Cygwin: setjmp/longjmp: decrement incyg after signal handling
Corinna Vinschen
corinna@sourceware.org
Fri Dec 6 10:47:43 GMT 2024
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=60fa8d793f867d896b824c66789c48e86dec4ea7
commit 60fa8d793f867d896b824c66789c48e86dec4ea7
Author: Corinna Vinschen <corinna@vinschen.de>
AuthorDate: Wed Dec 4 13:50:17 2024 +0100
Commit: Corinna Vinschen <corinna@vinschen.de>
CommitDate: Fri Dec 6 11:43:17 2024 +0100
Cygwin: setjmp/longjmp: decrement incyg after signal handling
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 <corinna@vinschen.de>
(cherry picked from commit 41e1013e6846f1774dfec085ff983990f67e6437)
Diff:
---
winsup/cygwin/scripts/gendef | 1 +
1 file changed, 1 insertion(+)
diff --git a/winsup/cygwin/scripts/gendef b/winsup/cygwin/scripts/gendef
index bb87ab55e557..e02d3503cc75 100755
--- a/winsup/cygwin/scripts/gendef
+++ b/winsup/cygwin/scripts/gendef
@@ -334,6 +334,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
More information about the Cygwin-cvs
mailing list