Cygwin 3.4.3 and 3.5.0... hangs in make, top, procps, ls /proc/PID/...

Corinna Vinschen corinna-cygwin@cygwin.com
Mon Jan 9 17:13:26 GMT 2023


On Jan  2 11:32, Takashi Yano via Cygwin wrote:
> On Thu, 29 Dec 2022 21:59:45 -0700
> Brian Inglis wrote:
> > I got some hangs (deadlock?) between (parallel?) make jobs, top, procps, and 
> > even ls /proc/*/ when trying to cygport all check curl or look at the process 
> > statuses when builds hung under Cygwin 3.4.3 and 3.5.0-0.69...
> > [...]
> I have looked into this issue a bit, and found that
> q->sigtls becomes sometimes NULL and access violation
> occurs at the following code.
> 
> winsup/cygwin/sigproc.cc: 1378
> 		if (q->sigtls->sigmask & (bit = SIGTOMASK (q->si.si_signo)))
> 		  {
> 		    tl_entry = cygheap->find_tls (q->si.si_signo, issig_wait);
> 
> I'm not sure why this happens, however it seems that
> the following patch fixes the issue.
> 
> diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
> index ce36c8be3..90eaa2a47 100644
> --- a/winsup/cygwin/sigproc.cc
> +++ b/winsup/cygwin/sigproc.cc
> @@ -1375,6 +1375,8 @@ wait_sig (VOID *)
>  	    *pack.mask = 0;
>  	    while ((q = q->next))
>  	      {
> +		if (q->sigtls == NULL)
> +		  continue;
>  		if (q->sigtls->sigmask & (bit = SIGTOMASK (q->si.si_signo)))
>  		  {
>  		    tl_entry = cygheap->find_tls (q->si.si_signo, issig_wait);
> 
> Corinna, could you please have a look?

If q->sigtls is NULL, the signal is nevertheless waiting for being
handled.  It's just not directed at a specific thread.  Beats me, why
this didn't occur in my testing.  The process signal info should contain
the process-wide mask of pending signals as well, obviously, so the
following patch should do the right thing:

diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index ce36c8be37fb..86e4e607ab7e 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -1375,7 +1375,8 @@ wait_sig (VOID *)
 	    *pack.mask = 0;
 	    while ((q = q->next))
 	      {
-		if (q->sigtls->sigmask & (bit = SIGTOMASK (q->si.si_signo)))
+		_cygtls *sigtls = q->sigtls ?: _main_tls;
+		if (sigtls->sigmask & (bit = SIGTOMASK (q->si.si_signo)))
 		  {
 		    tl_entry = cygheap->find_tls (q->si.si_signo, issig_wait);
 		    if (tl_entry)

Can you confirm?


Thanks,
Corinna


More information about the Cygwin mailing list