Date: Sun, 15 Aug 2004 17:21:27 -0700 (PDT) From: Jake Hamby <jhamby@anobject.com> To: FreeBSD-gnats-submit@FreeBSD.org Subject: kern/70502: error in new __thread local storage support Message-ID: <200408160021.i7G0LRYC003133@localhost.my.domain> Resent-Message-ID: <200408160030.i7G0UPg4037476@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>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@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:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200408160021.i7G0LRYC003133>