This is the mail archive of the
glibc-bugs@sourceware.org
mailing list for the glibc project.
[Bug nptl/3086] when run tst-timer on x86_64, it causes a segfault
- From: "huangjq at cn dot ibm dot com" <sourceware-bugzilla at sourceware dot org>
- To: glibc-bugs at sources dot redhat dot com
- Date: 12 Sep 2006 11:14:15 -0000
- Subject: [Bug nptl/3086] when run tst-timer on x86_64, it causes a segfault
- References: <20060818091057.3086.huangjq@cn.ibm.com>
- Reply-to: sourceware-bugzilla at sourceware dot org
------- 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.