[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#175511: errno is mishandled by libc in multithreaded programs



On Tuesday,  7 Jan, Daniel Jacobowitz wrote:
> Libcurl correctly uses __errno_location(); I assume the others do also. 
> That makes the failure quite surprising.  Can you produce a test case
> for this?

Here is a test case which also correctly uses __errno_location().  This
program produces roughly the following output:
T1: Expected error, got errno == 0.
T2: OK
T1: Expected error, got errno == 0.
T1: Expected error, got errno == 0.
T2: OK
T1: Expected error, got errno == 0.
T2: OK
Here thread 1 finds errno == 0 after a failed call to close(555).
This doesn't happen if the program is linked statically.

Nikita
#define _REENTRANT

#include <stdio.h>
#include <errno.h>
#include <sys/time.h>
#include <pthread.h>

static void * t1_routine(void *arg)
{
    unsigned long i;

    errno = 0;

    for (;;)
    {
        close(555);
        if (errno == 0)
            printf("T1: Expected error, got errno == 0.\n");
        else
            printf("T1: OK\n");
        for (i = 1000000; i; --i);
    }
}

static void * t2_routine(void *arg)
{
    unsigned long i;
    struct timeval tv;

    errno = 0;

    for (;;)
    {
        gettimeofday(&tv, 0);
        if (errno != 0)
            printf("T2: Expected no error, got %d.\n", errno);
        else
            printf("T2: OK\n");
        for (i = 1234567; i; --i);
    }
}

int main()
{
    pthread_t t1, t2;

    pthread_create(&t1, 0, t1_routine, 0);
    pthread_create(&t2, 0, t2_routine, 0);

    for (;;)
        sleep(1);

    return 0;
}

Reply to: