ProcessManager on Solaris

Eric Botcazou ebotcazou@libertysurf.fr
Wed Feb 16 02:29:00 GMT 2005


Hi,

As exhibited in http://gcc.gnu.org/ml/gcc-testresults/2005-02/msg00579.html ,
we have a problem with the ProcessManager on SPARC/Solaris: it randomly 
deadlocks.

The problem is the call to sigsuspend in waitForSignal:

  // Wait for SIGCHLD
  sigset_t mask;
  pthread_sigmask (0, NULL, &mask);
  sigdelset (&mask, SIGCHLD);

  // Use sigsuspend() instead of sigwait() as sigwait() doesn't play
  // nicely with the GC's use of signals.
  sigsuspend (&mask);

which appears to rely on the following property:

  // SIGCHLD is blocked in all threads in posix-threads.cc.
  // Setup the SIGCHLD handler.
  struct sigaction sa;
  memset (&sa, 0, sizeof (sa));


That's not true, at least on Solaris: another thread can accept SIGCHLD, the 
Boehm GC deamon thread.  For Process_5.java, the latter thread (id:2) is 
consistently picked up when a child process terminates instead of the thread 
of the ProcessManager (id:4).  As a proof, if the following lines are added 
to the signal handler:

  pthread_t self = pthread_self();
  if (self != (pthread_t)4)
    pthread_kill ((pthread_t) 4, SIGCHLD);

the testcase passes, with the following sequence of events:

poog% ./Process_5
reap: pid = -1
waiting...
SIGCHLD handler called
 by thread 4
done waiting.
reap: pid = 0
waiting...
SIGCHLD handler called
 by thread 2
SIGCHLD handler called
 by thread 4
done waiting.
reap: pid = 27325
reap: notifyAll() invoked
reap: pid = -1
ok


The proper solution would be to block SIGCHLD in the Boehm GC thread, but I 
don't know whether this is easily doable.

What's the best approach to solving this problem?  Thanks in advance.

-- 
Eric Botcazou



More information about the Java mailing list