[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