sigproc_init() handling CreateThread() failures

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

sigproc_init() handling CreateThread() failures

Max Kaehn
I was debugging a frozen job (in the mysql build) and ran into an
interesting stack trace:

#0  0x61093427 in wait_for_sigthread ()
    at ../../../../winsup/cygwin/sigproc.cc:136
#1  0x61094221 in sig_send (p=0x0, si=@0x23ab30, tls=0x0)
    at ../../../../winsup/cygwin/sigproc.cc:560
#2  0x61094810 in sig_send (p=0x1dc0, sig=6)
    at ../../../../winsup/cygwin/sigproc.cc:519
#3  0x61095e6e in sigproc_terminate (es=ES_FINAL)
    at ../../../../winsup/cygwin/sigproc.cc:505
#4  0x6106e964 in pinfo::exit (this=0x6, n=1)
    at ../../../../winsup/cygwin/pinfo.cc:151
#5  0x61004f01 in __api_fatal (
    fmt=0x611057c4 "CreateThread failed for %s - %p<%p>, %E")
    at ../../../../winsup/cygwin/dcrt0.cc:1167
#6  0x610036c5 in cygthread::cygthread (this=???, start=???, n=???, param=???,
    name=???, notify=???) at ../../../../winsup/cygwin/cygthread.cc:214

buf in frame 5 is "C:\\cygwin\\bin\\bash.exe: *** fatal error -
CreateThread failed for sig - 0x0<0x0>, Win32 error 0".  This
suggests that what's happening is that sigproc_init()
initializes wait_sig_inited, calls the cygthread constructor,
CreateThread fails (though that Win32 error 0 is just a little
suspicious), and calls api_fatal().  When pinfo::exit() calls
sigproc_terminate(), sig_send() sees that wait_sig_inited
is nonzero and calls wait_for_sigthread()-- but the sigthread
hasn't started yet.

I notice that no_signals_available() tests my_sendsig using !.
INVALID_HANDLE_VALUE is -1.  If no_signals_available() evaluates
to true, that should prevent sig_send() from getting to the
wait_for_sigthread() when there's no sigthread to wait for.
Here's the patch:


2006-01-05  Max Kaehn  <[hidden email]>

        * sigproc.cc (no_signals_available):  test for my_sendsig ==
        INVALID_HANDLE_VALUE.



Index: winsup/cygwin/sigproc.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/sigproc.cc,v
retrieving revision 1.271
diff -u -p -r1.271 sigproc.cc
--- winsup/cygwin/sigproc.cc    5 Jan 2006 16:26:22 -0000       1.271
+++ winsup/cygwin/sigproc.cc    5 Jan 2006 20:39:50 -0000
@@ -39,7 +39,7 @@ details. */
 #define WSSC             60000 // Wait for signal completion
 #define WPSP             40000 // Wait for proc_subproc mutex

-#define no_signals_available(x) (!my_sendsig || ((x) && myself->exitcode & EXITCODE_SET) || &_my_tls == _sig_tls)
+#define no_signals_available(x) (!my_sendsig || my_sendsig == INVALID_HANDLE_VALUE || ((x) && myself->exitcode & EXITCODE_SET) || &_my_tls == _sig_tls)

 #define NPROCS 256




Reply | Threaded
Open this post in threaded view
|

Re: sigproc_init() handling CreateThread() failures

Christopher Faylor-2
On Thu, Jan 05, 2006 at 12:50:47PM -0800, Max Kaehn wrote:
>I notice that no_signals_available() tests my_sendsig using !.
>INVALID_HANDLE_VALUE is -1.  If no_signals_available() evaluates to
>true, that should prevent sig_send() from getting to the
>wait_for_sigthread() when there's no sigthread to wait for.  Here's the
>patch:

But, that is the whole point of setting my_sendsig to INVALID_HANDLE_VALUE.

>2006-01-05  Max Kaehn  <[hidden email]>
>
> * sigproc.cc (no_signals_available):  test for my_sendsig ==
> INVALID_HANDLE_VALUE.

This seems like it should work.  Does it have the same effect?

cgf

Index: sigproc.cc
===================================================================
RCS file: /cvs/uberbaum/winsup/cygwin/sigproc.cc,v
retrieving revision 1.271
diff -u -p -r1.271 sigproc.cc
--- sigproc.cc 5 Jan 2006 16:26:22 -0000 1.271
+++ sigproc.cc 5 Jan 2006 21:16:49 -0000
@@ -39,7 +39,7 @@ details. */
 #define WSSC  60000 // Wait for signal completion
 #define WPSP  40000 // Wait for proc_subproc mutex
 
-#define no_signals_available(x) (!my_sendsig || ((x) && myself->exitcode & EXITCODE_SET) || &_my_tls == _sig_tls)
+#define no_signals_available(x) (!hwait_sig || ((x) && myself->exitcode & EXITCODE_SET) || &_my_tls == _sig_tls)
 
 #define NPROCS 256
 
@@ -61,6 +61,7 @@ HANDLE NO_COPY signal_arrived; // Event
 
 HANDLE NO_COPY sigCONT; // Used to "STOP" a process
 
+Static cygthread *hwait_sig;
 Static HANDLE wait_sig_inited; // Control synchronization of
  //  message queue startup
 
@@ -483,9 +484,8 @@ sigproc_init ()
    */
   sync_proc_subproc.init ("sync_proc_subproc");
 
-  my_sendsig = INVALID_HANDLE_VALUE; // changed later
   sync_startup = NULL;
-  cygthread *hwait_sig = new cygthread (wait_sig, 0, cygself, "sig");
+  hwait_sig = new cygthread (wait_sig, 0, cygself, "sig");
   hwait_sig->zap_h ();
 
   global_sigs[SIGSTOP].sa_flags = SA_RESTART | SA_NODEFER;
@@ -1141,6 +1141,7 @@ wait_sig (VOID *)
     }
   break;
  case __SIGEXIT:
+  hwait_sig = NULL;
   sigproc_printf ("saw __SIGEXIT");
   break; /* handle below */
  default:

Reply | Threaded
Open this post in threaded view
|

Re: sigproc_init() handling CreateThread() failures

Max Kaehn
On Thu, 2006-01-05 at 16:17 -0500, Christopher Faylor wrote:
> But, that is the whole point of setting my_sendsig to
> INVALID_HANDLE_VALUE.

Which I would've picked up if I had read the change log (RTFCL). :-P

> >       * sigproc.cc (no_signals_available):  test for my_sendsig ==
> >       INVALID_HANDLE_VALUE.

> This seems like it should work.  Does it have the same effect?

It looks good; I'll put it on the test machine and fire it up.  I
can usually get the problem to reproduce by leaving a cycle of
repeated builds running overnight, and I'll post the result
to this thread tomorrow.




Reply | Threaded
Open this post in threaded view
|

Re: sigproc_init() handling CreateThread() failures

Max Kaehn
On Thu, 2006-01-05 at 13:52 -0800, Max Kaehn wrote:

> On Thu, 2006-01-05 at 16:17 -0500, Christopher Faylor wrote:
> > But, that is the whole point of setting my_sendsig to
> > INVALID_HANDLE_VALUE.
>
> Which I would've picked up if I had read the change log (RTFCL). :-P
>
> > >       * sigproc.cc (no_signals_available):  test for my_sendsig ==
> > >       INVALID_HANDLE_VALUE.
>
> > This seems like it should work.  Does it have the same effect?
>
> It looks good; I'll put it on the test machine and fire it up.  I
> can usually get the problem to reproduce by leaving a cycle of
> repeated builds running overnight, and I'll post the result
> to this thread tomorrow.

20 builds haven't reproduced the problem.  Thanks!