This is the mail archive of the glibc-bugs@sourceware.org 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]
Other format: [Raw text]

[Bug nptl/3086] when run tst-timer on x86_64, it causes a segfault


------- Additional Comments From huangjq at cn dot ibm dot com  2006-09-12 11:14 -------
##################################################
nptl/sysdeps/unix/sysv/linux/timer_routines.c
##################################################
static void *
timer_helper_thread (void *arg)
{
.....
      int result = INLINE_SYSCALL (rt_sigtimedwait, 4, &ss, &si, NULL,
                                   _NSIG / 8);

      LIBC_CANCEL_RESET (oldtype);

      if (result > 0)
        {       
          if (si.si_code == SI_TIMER)
            {       
              struct timer *tk = (struct timer *) si.si_ptr;

              /* That the signal we are waiting for.  */
              pthread_t th;
              (void) pthread_create (&th, &tk->attr, timer_sigev_thread, tk);
            }
......

static void *
timer_sigev_thread (void *arg)
{
  /* The parent thread has all signals blocked.  This is a bit
     surprising for user code, although valid.  We unblock all
     signals.  */
  sigset_t ss;
  sigemptyset (&ss);
  INTERNAL_SYSCALL_DECL (err);
  INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_SETMASK, &ss, NULL, _NSIG / 8);

  struct timer *tk = (struct timer *) arg;	<----- critical section

  /* Call the user-provided function.  */
  tk->thrfunc (tk->sival);

  return NULL;
}

##############################################
/nptl/sysdeps/unix/sysv/linux/timer_delete.c
##############################################
int
timer_delete (timerid)
     timer_t timerid;
{
# undef timer_delete
# ifndef __ASSUME_POSIX_TIMERS
  if (__no_posix_timers >= 0)
# endif
    {
      struct timer *kt = (struct timer *) timerid;

      /* Delete the kernel timer object.  */
      int res = INLINE_SYSCALL (timer_delete, 1, kt->ktimerid);

      if (res == 0)
        {
# ifndef __ASSUME_POSIX_TIMERS
          /* We know the syscall support is available.  */
          __no_posix_timers = 1;
# endif

          /* Free the memory.  */
          (void) free (kt);		     <----- critical section

          return 0;
        }

>From above code, we can see, when a timer event trigger, it will create a 
thread and invoke function timer_sigev_thread(supposing it running on CPU0), 
before this thread access the struct tk, this program(tst-timer) call 
timer_delete to delete this struct, yes, it succeed, this struct is freed by 
timer_delete(supposing it running on CPU1), now when the first thread try to 
access tk, it will cause a segfault, I suspect this problem only exists on SMP 
machine. when we compile tst-timer.c to 32-bit, it work fine, I don't know 
why? here is a patch from drepper:
from the nptl/Changelog

http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/nptl/ChangeLog.diff?
r1=1.888&r2=1.889&cvsroot=glibc

2006-04-27  Ulrich Drepper  <drepper@redhat.com>
       * sysdeps/unix/sysv/linux/timer_routines.c (timer_helper_thread):
         Allocate new object which is passed to timer_sigev_thread so that
         the timer can be deleted before the new thread is scheduled.

This is the fix in question.

http://sources.redhat.com/cgi-
bin/cvsweb.cgi/libc/nptl/sysdeps/unix/sysv/linux/timer_routines.c.diff?
r1=1.8&r2=1.9&cvsroot=glibc

-- 


http://sourceware.org/bugzilla/show_bug.cgi?id=3086

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.


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