[newlib-cygwin] Cygwin: signal: Revive toggling incyg flag in call_signal_handler()
Takashi Yano
tyan0@sourceware.org
Sat May 3 06:07:38 GMT 2025
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=b7097ab39ed0931fd50425531df812b3258bcc05
commit b7097ab39ed0931fd50425531df812b3258bcc05
Author: Takashi Yano <takashi.yano@nifty.ne.jp>
Date: Sat May 3 14:49:23 2025 +0900
Cygwin: signal: Revive toggling incyg flag in call_signal_handler()
The commit 68991cda8185 dropped toggling incyg flag in the function
call_signal_handler(). However this seems to cause another problem
that the command "stress-ng --kill 0 -t 5" sometimes leaves child
processes hanging. With this patch additional mechanism to determin
whether the target thread is inside cygwin1.dll has been introduced
instead. This mechanism utilizes _cygtls::inside_kernel() function
with additional argument to return true if the code is in the cygwin
DLL even if incyg flag is not set.
Fixes: 68991cda8185 ("Cygwin: signal: Do not handle signals while waiting for wakeup evt")
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
Diff:
---
winsup/cygwin/exceptions.cc | 9 +++++++--
winsup/cygwin/local_includes/cygtls.h | 2 +-
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index d1c98e46f..9763a1b04 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -440,7 +440,7 @@ cygwin_exception::dumpstack ()
}
bool
-_cygtls::inside_kernel (CONTEXT *cx)
+_cygtls::inside_kernel (CONTEXT *cx, bool inside_cygwin)
{
int res;
MEMORY_BASIC_INFORMATION m;
@@ -462,6 +462,8 @@ _cygtls::inside_kernel (CONTEXT *cx)
else if (h == hntdll)
res = true; /* Calling GetModuleFilename on ntdll.dll
can hang */
+ else if (h == cygwin_hmodule && inside_cygwin)
+ res = true;
else if (h == user_data->hmodule)
res = false;
else if (!GetModuleFileNameW (h, checkdir,
@@ -921,7 +923,7 @@ _cygtls::interrupt_now (CONTEXT *cx, siginfo_t& si, void *handler,
/* Delay the interrupt if we are
1) somehow inside the DLL
2) in a Windows DLL. */
- if (incyg || inside_kernel (cx))
+ if (incyg || inside_kernel (cx, true))
interrupted = false;
else
{
@@ -1756,6 +1758,7 @@ _cygtls::call_signal_handler ()
int this_errno = saved_errno;
reset_signal_arrived ();
+ incyg = false;
current_sig = 0; /* Flag that we can accept another signal */
/* We have to fetch the original return address from the signal stack
@@ -1868,6 +1871,8 @@ _cygtls::call_signal_handler ()
}
unlock ();
+ incyg = true;
+
set_signal_mask (_my_tls.sigmask, (this_sa_flags & SA_SIGINFO)
? context1.uc_sigmask : this_oldmask);
if (this_errno >= 0)
diff --git a/winsup/cygwin/local_includes/cygtls.h b/winsup/cygwin/local_includes/cygtls.h
index 079ada99a..4698352ae 100644
--- a/winsup/cygwin/local_includes/cygtls.h
+++ b/winsup/cygwin/local_includes/cygtls.h
@@ -229,7 +229,7 @@ public: /* Do NOT remove this public: line, it's a marker for gentls_offsets. */
bool interrupt_now (CONTEXT *, siginfo_t&, void *, struct sigaction&);
void interrupt_setup (siginfo_t&, void *, struct sigaction&);
- bool inside_kernel (CONTEXT *);
+ bool inside_kernel (CONTEXT *, bool inside_cygwin = false);
void signal_debugger (siginfo_t&);
#ifdef CYGTLS_HANDLE
More information about the Cygwin-cvs
mailing list