kern/70502: error in new __thread local storage support
Jake Hamby
jhamby at anobject.com
Sun Aug 15 17:30:25 PDT 2004
>Number: 70502
>Category: kern
>Synopsis: error in new __thread local storage support
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Mon Aug 16 00:30:24 GMT 2004
>Closed-Date:
>Last-Modified:
>Originator: Jake Hamby
>Release: FreeBSD 5.2-CURRENT i386
>Organization:
Software Factory x
>Environment:
System: FreeBSD fuji 5.2-CURRENT FreeBSD 5.2-CURRENT #2: Sat Aug 14 19:00:56 PDT 2004 root at fuji:/usr/home/work/sys/FUJI i386
>Description:
The new __thread based TLS code doesn't seem to work beyond a particular size.
>How-To-Repeat:
See the attached test program. On my machine, it works for NUM_KEYS=6, but
with NUM_KEYS=10 I see data corruption in the TLS area, and with NUM_KEYS=64,
it crashes, so the TLS region is definitely overwriting something important.
$ gcc -O2 -o tls_nptl_test tls_nptl_test.c -lpthread
$ ./tls_nptl_test
Fatal error '_pq_remove: Not in priority queue' at line 144 in file /usr/src/lib/libpthread/thread/thr_priority_queue.c (errno = 0)
Segmentation fault (core dumped)
>Fix:
I don't know the code well enough to suggest a fix.
--- tls_nptl_test.c begins here ---
/*
* Test of pthreads / TLS storage.
*/
#define _REENTRANT
#include <stdio.h>
#include <pthread.h>
#include <time.h>
#include <dlfcn.h>
#define NUM_THREADS 64
#define NUM_KEYS 64
static __thread int TLS_keys[NUM_KEYS];
static pthread_t threads[NUM_THREADS];
static void*
start_routine(void *arg)
{
int thread_num = (int)arg;
int i, err;
for(i=0; i<500; i++)
{
if (i==17)
{
/* printf("Thread %d: Number 17: break for debugger\n",
thread_num); */
}
int j;
for(j=0; j<NUM_KEYS; j++)
{
/* verify old key value (except first time through loop) */
int val = TLS_keys[j];
if (val != i && (i != 0))
{
printf("Thread %d: expected %d for key %d, found %d\n",
thread_num, i, j, val);
return (void*)1;
}
/* set new key value */
TLS_keys[j] = i+1;
}
/* sleep from 0.1 to 1 sec. */
struct timespec slptime = {0, 100000000 + random()%900000000};
/*printf("Thread %d: foo sleep %d\n", thread_num, slptime.tv_nsec);*/
nanosleep(&slptime, 0);
}
return 0;
}
int
main(int argc, char** argv)
{
int i;
const char* dlerr = dlerror();
if (dlerr)
{
printf("dlerror: %s\n", dlerr);
return 1;
}
for(i=0; i<NUM_THREADS; i++)
{
int err = pthread_create(&threads[i], NULL, start_routine,
(void*)i);
if (err)
{
printf("pthread_create error %d for thread %d\n", err, i);
return 1;
}
}
for(i=0; i<NUM_THREADS; i++)
{
void* retval;
int err = pthread_join(threads[i], &retval);
if (err)
{
printf("pthread_join error %d for thread %d\n", err, i);
return 1;
}
}
return 0;
}
--- tls_nptl_test.c ends here ---
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list