>Number: 160721 >Category: misc >Synopsis: TLS is inconsistent >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Wed Sep 14 02:10:10 UTC 2011 >Closed-Date: >Last-Modified: >Originator: Thinker K.F. Li >Release: FreeBSD 9.0-CURRENT i386 >Organization: Allwitz Tech. >Environment: System: FreeBSD eeebox.branda.to 9.0-CURRENT FreeBSD 9.0-CURRENT #1: Sun Jun 5 17:08:32 CST 2011 thin...@eeebox.branda.to:/usr/src/sys/i386/compile/eeebox i386
>Description: Compiler generated code will call ___tls_get_addr() of ld-elf.so for TLS variable. It is supposed to return the same address, every time, for the same passed address and thread, but it does not. >How-To-Repeat: Compile following code with commands 1. cc -shared -o test-tls-1.so -pthread -fpic test-tls-1.c 2. cc -o test-tls -pthread test-tls.c test-tls is supposed to print "100" on stdout, but it print out "50", instead. If you dig into opcodes, you will find that ___tls_get_addr() return two different base addresses for modify() and for show() respective. This issue is only making troubles for programs accessing TLS after dlopen(). --- test-tls-1.c begins here --- #include <stdio.h> __thread int var = 50; void modify(void) { var = 100; } void show(void) { printf("%d\n", var); } --- test-tls-1.c ends here --- --- test-tls.c begins here --- #include <stdio.h> #include <dlfcn.h> int main(int argc, char * const *argv) { void (*modify)(void); void (*modify)(void); void *sohdl; sohdl = dlopen("./test-tls-1.so", RTLD_NOW); modify = (void (*)(void))dlsym(sohdl, "modify"); show = (void (*)(void))dlsym(sohdl, "show"); modify(); show(); return 0; } --- test-tls.c ends here --- >Fix: Apply following patch on the root of source tree can fix this issue. --- libexec-rtld_elf-rtld.c.diff begins here --- --- libexec/rtld-elf/rtld.c.orig 2011-09-13 14:25:17.000000000 +0800 +++ libexec/rtld-elf/rtld.c 2011-09-13 14:25:43.000000000 +0800 @@ -3371,6 +3371,7 @@ free(dtv); lock_release(rtld_bind_lock, &lockstate); *dtvp = newdtv; + dtv = newdtv; } /* Dynamically allocate module TLS if necessary */ --- libexec-rtld_elf-rtld.c.diff ends here --- >Release-Note: >Audit-Trail: >Unformatted: _______________________________________________ freebsd-bugs@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-bugs To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"