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: