Ver código fonte

Hi Erik and Manuel

Long time no see :)

It appears uClibc pthreads native debugging is broken w.r.t thread exit handling in
uClibc(at least on PPC). When debugging ex7, gdb(6.2.1) bails out as
soon as a thread exits. I found a comment in gdb that TD_DEATH handling was broken for
glibc 2.3.1, so I figured that maybe it was broken in uClibc also.

I added a #if 0 #endif in pthread_exit( see patch below) and then
gdb behaved again.

While looking into this I found a few differences( included in the patch)
between glibc and uClibc. Don't know if these makes a difference, but I leave that to
you to decide.

 Jocke
Eric Andersen 19 anos atrás
pai
commit
badf6dd685

+ 3 - 1
libpthread/linuxthreads/join.c

@@ -52,10 +52,11 @@ PDEBUG("self=%p, pid=%d\n", self, self->p_pid);
       uint32_t mask = __td_eventmask (TD_DEATH);
 
       if ((mask & (__pthread_threads_events.event_bits[idx]
-		   | THREAD_GETMEM(self,
+		   | THREAD_GETMEM_NC(self,
 				   p_eventbuf.eventmask).event_bits[idx]))
 	  != 0)
 	{
+#if 0 /* Appears like DEATH event reporting is broken */
 	  /* Yep, we have to signal the death.  */
 	  THREAD_SETMEM(self, p_eventbuf.eventnum, TD_DEATH);
 	  THREAD_SETMEM(self, p_eventbuf.eventdata, self);
@@ -63,6 +64,7 @@ PDEBUG("self=%p, pid=%d\n", self, self->p_pid);
 
 	  /* Now call the function to signal the event.  */
 	  __linuxthreads_death_event();
+#endif
 	}
     }
   /* See if someone is joining on us */

+ 5 - 0
libpthread/linuxthreads/pthread.c

@@ -376,6 +376,7 @@ static void pthread_initialize(void)
   sa.sa_flags = 0;
   __libc_sigaction(__pthread_sig_restart, &sa, NULL);
   sa.sa_handler = pthread_handle_sigcancel;
+  sigaddset(&sa.sa_mask, __pthread_sig_restart);
   // sa.sa_flags = 0;
   __libc_sigaction(__pthread_sig_cancel, &sa, NULL);
   if (__pthread_sig_debug > 0) {
@@ -388,6 +389,10 @@ static void pthread_initialize(void)
   sigemptyset(&mask);
   sigaddset(&mask, __pthread_sig_restart);
   sigprocmask(SIG_BLOCK, &mask, NULL);
+  /* And unblock __pthread_sig_cancel if it has been blocked. */
+  sigdelset(&mask, __pthread_sig_restart);
+  sigaddset(&mask, __pthread_sig_cancel);
+  sigprocmask(SIG_UNBLOCK, &mask, NULL);
   /* Register an exit function to kill all other threads. */
   /* Do it early so that user-registered atexit functions are called
      before pthread_onexit_process. */