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