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.y...@nifty.ne.jp>
---
 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
-- 
2.45.1

Reply via email to