>Number:         6417
>Category:       library
>Synopsis:       pthread_exit() final thread hangs
>Confidential:   yes
>Severity:       serious
>Priority:       medium
>Responsible:    bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   unknown
>Arrival-Date:   Wed Jun 30 12:00:01 GMT 2010
>Closed-Date:
>Last-Modified:
>Originator:     
>Release:        
>Organization:
>Environment:
        System      : OpenBSD 4.6
        Details     : OpenBSD 4.6 (GENERIC) #43: Thu Jul  9 21:34:21 MDT
2009 [email protected]:/usr/src/sys/arch/sparc64/compile/GENERIC
        Architecture: OpenBSD.sparc64
        Machine     : sparc64
>Description:
        After creating one mutex and two threads, pthread_exit() hangs
        on the final thread.
        The code works fine without creating that mutex.

>How-To-Repeat:

        Code to trigger.
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>

void* run(void* arg)
{
        (void)arg;
        return NULL;
}

int main(void)
{
        pthread_t t[10];
        int i, num=2;
        pthread_mutex_t m;

        printf("mutex init\n");
        pthread_mutex_init(&m, NULL);

        printf("pthread create %d threads\n", num);
        for(i=0; i<num; i++) {
                pthread_create(&t[i], NULL, run, NULL);
        }
        for(i=0; i<num; i++) {
                pthread_join(t[i], NULL);
        }
        printf("pthread joined %d threads\n", num);

        pthread_mutex_destroy(&m);
        printf("mutex destroyed\n");

        printf("pthread_exit\n");
        pthread_exit(NULL);
}

then gcc -pthread the file and run.  It does not exit.  gdb says
#0  0x00000000479903e8 in poll () from /usr/lib/libc.so.51.0
#1  0x0000000047325d6c in _thread_kern_poll (wait_reqd=0)
    at /usr/src/lib/libpthread/uthread/uthread_kern.c:760
#2  0x0000000047325770 in _thread_kern_sched (scp=0x0)
    at /usr/src/lib/libpthread/uthread/uthread_kern.c:382
#3  0x00000000473230c4 in pthread_cond_timedwait (cond=0x4752c110,
    mutex=0x4752c108, abstime=0x4b861e70)
    at /usr/src/lib/libpthread/uthread/uthread_cond.c:431
#4  0x000000004731afb4 in _thread_gc (arg=0x0)
    at /usr/src/lib/libpthread/uthread/uthread_gc.c:181
#5  0x000000004731ac78 in _thread_start ()
    at /usr/src/lib/libpthread/uthread/uthread_create.c:240
#6  0x000000004731ac40 in pthread_create (thread=0x0, attr=0x0,
    start_routine=0, arg=0x0)
    at /usr/src/lib/libpthread/uthread/uthread_create.c:229


#1:    at /usr/src/lib/libpthread/uthread/uthread_kern.c:760
760             count = _thread_sys_poll(_thread_pfd_table, nfds,
timeout_ms);
(gdb) print timeout_ms
$1 = 10009
(gdb) print nfds
$2 = 1
(gdb) print _thread_pfd_table
$3 = (struct pollfd *) 0x40e5c000
(gdb) print *_thread_pfd_table
$4 = {fd = 6, events = 64, revents = 0}

#2 is from:
                /*
                 * There are no threads ready to run, so wait until
                 * something happens that changes this condition:
                 */
                _thread_kern_poll(1);
But this never happens because there are no more threads.  Instead it
seems the code should have passed
        /* There are no more threads, so exit this process: */
        exit(0);

>Fix:
        The poll() call in pthread library is hanging.
        The garbage collector thread in
/usr/src/lib/libpthread/uthread/uthread_gc.c line 87,
                /* Check if this is the last running thread: */
                if (TAILQ_FIRST(&_thread_list) == curthread &&
                    TAILQ_NEXT(curthread, tle) == NULL)
                        /*
                         * This is the last thread, so it can exit
                         * now.
                         */
                        f_done = 1;
        Could it be that this line fails to fire because the GC thread
        is also part of that list?  At exit gdb says:
(gdb) print _thread_list
$1 = {tqh_first = 0x479d8400, tqh_last = 0x479d8030}



(gdb) print *_thread_list->tqh_first
$4 = {magic = 3499860245, name = 0x429fa050 "GC", lock = {
    access_lock = 0 '\0', lock_owner = 0x0, fname = 0x0, lineno = 0},
tle = {
    tqe_next = 0x479d8000, tqe_prev = 0x425f0148}, dle = {tqe_next = 0x0,
    tqe_prev = 0x0}, start_routine = 0x423decc0 <_thread_gc>, arg = 0x0,
  stack = 0x4f5b2500, attr = {sched_policy = 3, sched_inherit = 0,
    sched_interval = 20000, prio = 15, suspend = 0, flags = 0, arg_attr
= 0x0,
    cleanup_attr = 0, stackaddr_attr = 0x0, stacksize_attr = 524288,
    guardsize_attr = 8192}, saved_sigcontext = {sc_onstack = 0,
    __sc_mask13 = 0, sc_sp = 0, sc_pc = 0, sc_npc = 0, sc_tstate = 0,
    sc_g1 = 0, sc_o0 = 0, sc_mask = 0}, _machdep = {fp = 1226265537,
    pc = 1111398552, fs_fprs = 0, fs_fsr = 0, fs_regs = {
      0 <repeats 32 times>}}, sig_saved = 0, cancelflags = 4,
  suspended = SUSP_NO, continuation = 0, sigmask = 4294967295, sigpend = 0,
  state = PS_COND_WAIT, last_active = 0, last_inactive = 0, slice_usec =
- -1,
  wakeup_time = {tv_sec = 1277890581, tv_nsec = 852304037}, timeout = 0,
  error = 0, joiner = 0x0, join_status = {thread = 0x0, ret = 0x0, error
= 0},
  pqe = {tqe_next = 0x0, tqe_prev = 0x479d8280}, sqe = {tqe_next = 0x0,
    tqe_prev = 0x479d8290}, qe = {tqe_next = 0x0, tqe_prev = 0x0}, data = {
    mutex = 0x429fc500, cond = 0x429fc500, sigwait = 0x429fc500, fd =
{fd = 0,
      branch = 1117766912, fname = 0x0}, fp = 0x429fc500,
    poll_data = 0x429fc500, spinlock = 0x429fc500, thread = 0x429fc500},
  poll_data = {nfds = 0, fds = 0x0}, interrupted = 0, closing_fd = 0,
  signo = 0, sig_defer_count = 0, yield_on_sig_undefer = 0, flags = 133,
  base_priority = 15, inherited_priority = 0, active_priority = 15,
  priority_mutex_count = 0, rdlock_count = 0, mutexq = {tqh_first = 0x0,
    tqh_last = 0x479d8700}, ret = 0x0, specific_data = 0x0,
  specific_data_count = 0, cleanup = 0x0,
  fname = 0x424eef78 "/usr/src/lib/libpthread/uthread/uthread_cond.c",
  lineno = 432}
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/

iEYEARECAAYFAkwrEUkACgkQkDLqNwOhpPh0dACffNJVUZvVePRaV8LWdhU64JUu
C5gAoKFgMruhF9RXmxfnuUE6DbU0xK1j
=+L4l
>Audit-Trail:
>Unformatted:
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1

Reply via email to