This is the mail archive of the libc-hacker@sourceware.cygnus.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: gdb and linuxthreads (A deadlock in linuxthreads.)


> I have verified that there was no third thread at all. There were only
> 2 threads, the manager and the thread just sent a request to the
> manager. It may be a race condition which can only happen on a SMP
> machine.

Hmph.  That's interesting.  I'll try to think of a scenario that
explains this.  Sometimes, I fear the memory subsystem doesn't
implement strong ordering on memory accesses like it's supposed to do
according to the docs...

At any rate, you'll find below the patches that change the signal used
to report dead children.  The patches are against the current working
sources on anoncvs@glibc.cygnus.com.  I haven't been able to test them
on my home machine, but will test them tomorrow at work.  I'll also
test what happens with gdb.  Maybe the extra signals don't break
anything, just causing gdb to rescan the set of running threads
unnecessarily.

All the best,

- Xavier Leroy

Index: manager.c
===================================================================
RCS file: /glibc/cvsfiles/libc/linuxthreads/manager.c,v
retrieving revision 1.18
diff -c -r1.18 manager.c
*** manager.c	1998/10/29 14:34:19	1.18
--- manager.c	1998/12/20 09:22:02
***************
*** 101,111 ****
    /* Set the error variable.  */
    __pthread_manager_thread.p_errnop = &__pthread_manager_thread.p_errno;
    __pthread_manager_thread.p_h_errnop = &__pthread_manager_thread.p_h_errno;
!   /* Block all signals except __pthread_sig_restart, __pthread_sig_cancel
!      and SIGTRAP */
    sigfillset(&mask);
!   sigdelset(&mask, __pthread_sig_restart);
!   sigdelset(&mask, __pthread_sig_cancel); /* for debugging new threads */
    sigdelset(&mask, SIGTRAP);            /* for debugging purposes */
    sigprocmask(SIG_SETMASK, &mask, NULL);
    /* Raise our priority to match that of main thread */
--- 101,109 ----
    /* Set the error variable.  */
    __pthread_manager_thread.p_errnop = &__pthread_manager_thread.p_errno;
    __pthread_manager_thread.p_h_errnop = &__pthread_manager_thread.p_h_errno;
!   /* Block all signals except __pthread_sig_cancel and SIGTRAP */
    sigfillset(&mask);
!   sigdelset(&mask, __pthread_sig_cancel); /* for thread termination */
    sigdelset(&mask, SIGTRAP);            /* for debugging purposes */
    sigprocmask(SIG_SETMASK, &mask, NULL);
    /* Raise our priority to match that of main thread */
***************
*** 378,384 ****
  #ifdef CLONE_PTRACE
                  CLONE_PTRACE |
  #endif
! 		__pthread_sig_restart, new_thread);
    /* Check if cloning succeeded */
    if (pid == -1) {
      /* Free the stack if we allocated it */
--- 376,382 ----
  #ifdef CLONE_PTRACE
                  CLONE_PTRACE |
  #endif
! 		__pthread_sig_cancel, new_thread);
    /* Check if cloning succeeded */
    if (pid == -1) {
      /* Free the stack if we allocated it */
Index: pthread.c
===================================================================
RCS file: /glibc/cvsfiles/libc/linuxthreads/pthread.c,v
retrieving revision 1.12
diff -c -r1.12 pthread.c
*** pthread.c	1998/12/04 20:55:31	1.12
--- pthread.c	1998/12/20 09:22:04
***************
*** 459,467 ****
  
  /* The handler for the RESTART signal just records the signal received
     in the thread descriptor, and optionally performs a siglongjmp
!    (for pthread_cond_timedwait).
!    For the thread manager thread, redirect the signal to
!    __pthread_manager_sighandler. */
  
  #ifndef __i386__
  static void pthread_handle_sigrestart(int sig)
--- 459,465 ----
  
  /* The handler for the RESTART signal just records the signal received
     in the thread descriptor, and optionally performs a siglongjmp
!    (for pthread_cond_timedwait). */
  
  #ifndef __i386__
  static void pthread_handle_sigrestart(int sig)
***************
*** 474,491 ****
    asm volatile ("movw %w0,%%gs" : : "r" (ctx.gs));
    self = thread_self();
  #endif
!   if (self == &__pthread_manager_thread) {
!     __pthread_manager_sighandler(sig);
!   } else {
!     THREAD_SETMEM(self, p_signal, sig);
!     if (THREAD_GETMEM(self, p_signal_jmp) != NULL)
!       siglongjmp(*THREAD_GETMEM(self, p_signal_jmp), 1);
!   }
  }
  
  /* The handler for the CANCEL signal checks for cancellation
     (in asynchronous mode), for process-wide exit and exec requests.
!    For the thread manager thread, we ignore the signal.
     The debugging strategy is as follows:
     On reception of a REQ_DEBUG request (sent by new threads created to
     the thread manager under debugging mode), the thread manager throws
--- 472,486 ----
    asm volatile ("movw %w0,%%gs" : : "r" (ctx.gs));
    self = thread_self();
  #endif
!   THREAD_SETMEM(self, p_signal, sig);
!   if (THREAD_GETMEM(self, p_signal_jmp) != NULL)
!     siglongjmp(*THREAD_GETMEM(self, p_signal_jmp), 1);
  }
  
  /* The handler for the CANCEL signal checks for cancellation
     (in asynchronous mode), for process-wide exit and exec requests.
!    For the thread manager thread, redirect the signal to
!    __pthread_manager_sighandler.
     The debugging strategy is as follows:
     On reception of a REQ_DEBUG request (sent by new threads created to
     the thread manager under debugging mode), the thread manager throws
***************
*** 510,516 ****
  #endif
  
    if (self == &__pthread_manager_thread)
!     return;
    if (__pthread_exit_requested) {
      /* Main thread should accumulate times for thread manager and its
         children, so that timings for main thread account for all threads. */
--- 505,511 ----
  #endif
  
    if (self == &__pthread_manager_thread)
!     __pthread_manager_sighandler(sig);
    if (__pthread_exit_requested) {
      /* Main thread should accumulate times for thread manager and its
         children, so that timings for main thread account for all threads. */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]