[newlib-cygwin] Cygwin: signal: Revive toggling incyg flag in call_signal_handler()

Takashi Yano via Cygwin-cvs <[email protected]>
Newsgroups gmane.os.cygwin.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=b7097ab39ed0931fd50425531df812b3258bcc05

commit b7097ab39ed0931fd50425531df812b3258bcc05
Author: Takashi Yano <[email protected]>
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 <[email protected]>

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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.