This is the mail archive of the libc-help@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]

Condition variable deadlock with PI mutexes


I think I've found a bug causing a deadlock when using pthread condition variables with PRIO_INHERIT mutexes, or I'm missing something. I compile the program at the end of this email with the following options:

gcc -Wall -pthread -D_XOPEN_SOURCE=600 pi_condvar_bug.c

I'm running this on a Fedora 16 (x86_64) machine with gcc 4.6.2 and kernel 3.2.6-3.fc16.x86_64. I've tested both the Fedora supplied glibc (2.14.90-24) and a custom built 2.14 with identical results. I've also built a 32 bit binary using -m32, which again produced identical results.

If I run the program in GDB and break after the deadlock, I get the following backtrace:

(gdb) thread apply all backtrace

    Thread 4 (Thread 0x7ffff6fd4700 (LWP 28864)):
    #0  0x0000003b56405970 in __pthread_mutex_lock_full ()
       from /lib64/libpthread.so.0
    #1  0x00000000004009fd in consumer_thread ()
    #2  0x0000003b56407d90 in start_thread () from /lib64/libpthread.so.0
    #3  0x0000003b55cef48d in clone () from /lib64/libc.so.6

    Thread 3 (Thread 0x7ffff77d5700 (LWP 28863)):
    #0  0x0000003b5640bac8 in pthread_cond_wait@@GLIBC_2.3.2 ()
       from /lib64/libpthread.so.0
    #1  0x0000000000400a15 in consumer_thread ()
    #2  0x0000003b56407d90 in start_thread () from /lib64/libpthread.so.0
    #3  0x0000003b55cef48d in clone () from /lib64/libc.so.6

    Thread 2 (Thread 0x7ffff7fd6700 (LWP 28862)):
    #0  0x0000003b56406311 in __pthread_mutex_cond_lock_full ()
       from /lib64/libpthread.so.0
    #1  0x0000003b5640bb79 in pthread_cond_wait@@GLIBC_2.3.2 ()
       from /lib64/libpthread.so.0
    #2  0x0000000000400a15 in consumer_thread ()
    #3  0x0000003b56407d90 in start_thread () from /lib64/libpthread.so.0
    #4  0x0000003b55cef48d in clone () from /lib64/libc.so.6

    Thread 1 (Thread 0x7ffff7fd8700 (LWP 28859)):
    #0  0x0000003b56405970 in __pthread_mutex_lock_full ()
       from /lib64/libpthread.so.0
    #1  0x0000000000400b66 in main ()

If I run the binary built statically against vanilla 2.14, I can see more:

Program received signal SIGINT, Interrupt.
__pthread_mutex_lock_full (mutex=0x6be900) at pthread_mutex_lock.c:303
303 if (INTERNAL_SYSCALL_ERROR_P (e, __err)
(gdb) p *mutex
$1 = {__data = {__lock = -2147454520, __count = 1, __owner = 0, __nusers = 2,
__kind = 34, __spins = 0, __list = {__prev = 0x0, __next = 0x0}},
__size = "\310q\000\200\001\000\000\000\000\000\000\000\002\000\000\000\"", '\000' <repeats 22 times>,
__align = 6442480072}


The deadlock only happen if I set the PTHREAD_PRIO_INHERIT attribute on the mutex.

I'm considering filing a bug in bugzilla, but I wanted to check here first.

/Tobias

----------------------------------------------------------------------

#include <assert.h>
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>

pthread_cond_t g_cond;
pthread_mutex_t g_mutex;
int g_num, g_it;

void*
consumer_thread(void *arg)
{
    for (;;)
    {
        if (pthread_mutex_lock(&g_mutex))
            abort();
        while (g_num <= 0)
        {
            if (pthread_cond_wait(&g_cond, &g_mutex))
                abort();
        }
        printf("\r%9u", ++g_it);
        fflush(stdout);
        g_num--;
        if (pthread_mutex_unlock(&g_mutex))
            abort();
    }
}

void
init_mutex(void)
{
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    /* pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); */
    /* if (pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT)) */
        /* abort(); */
    if (pthread_mutex_init(&g_mutex, &attr))
        abort();
}

void
create_thread(void *(*thread_main)(void *))
{
    pthread_t t;
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
    if (pthread_create(&t, &attr, thread_main, NULL))
        abort();
}

int
main()
{
    int i;
    init_mutex();
    for (i = 0; i < 3; ++i)
        create_thread(consumer_thread);

    for (;;)
    {
        if (pthread_mutex_lock(&g_mutex))
            abort();
        g_num++;
        if (pthread_cond_signal(&g_cond))
            abort();
        if (pthread_mutex_unlock(&g_mutex))
            abort();
    }
}


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