Hello Daniel, 2013/12/21 Daniel Villeneuve <[email protected]>: > Hi, > > I have a DLL library which declares an "extern __thread int iTlsExtern" > variable, which I can access from the library and from a program. > > However, modifications made from the library to iTlsExtern are not > seen from the program. > > This seems to come from the fact that the address of the variable > from the library is different from the address from the program. > > I'm using gcc 4.8.2, binutils 2.24, mingw-w64-v3.0.0, > pthreads-w32-2-9-1-release. The program is compiled in 64-bit mode. > > My test program is given below (files lib.h, lib.c, prog.c and Makefile). > Running prog displays two different values for &iTlsExtern depending > on the address being taken from main or the library. After doing > iTlsExtern=2 in the library, the output from the library is correct but > the output from main is not. > > Is there something wrong with the code, the feature macros (from lib.h) > or the compilation flags in the Makefile)? > > Is there something else I can provide to investigate the problem? > -- > Daniel Villeneuve > > > ----- lib.h > #ifndef LIB_H > #define LIB_H > > #ifndef _POSIX_C_SOURCE > #define _POSIX_C_SOURCE 200809L > #endif > > #ifndef _MT > #define _MT 1 > #endif > > #include <stdio.h> > > #define EXPORT __declspec(dllexport) > #define IMPORT __declspec(dllimport) > #define thread_local __thread > > extern thread_local LIB_DLLPORT int iTlsExtern; > > extern LIB_DLLPORT void LibDebug(void); > extern LIB_DLLPORT void LibInit(int); > > #endif > > ----- lib.c > #include "lib.h" > > thread_local int iTlsExtern; > > void LibDebug(void) > { > fprintf(stderr, "&iTlsExtern (from LibDebug) = %p\n", (void > *)&iTlsExtern); > fprintf(stderr, " iTlsExtern (from LibDebug) = %d\n", iTlsExtern); > } > > void LibInit(int i) > { > fprintf(stderr, " setting iTlsExtern to %d (from LibDebug)\n", i); > iTlsExtern = i; > } > > ----- prog.c > #include <stdio.h> > #include "lib.h" > > static void MainDebug(void) > { > fprintf(stderr, "&iTlsExtern (from MainDebug) = %p\n", (void > *)&iTlsExtern); > fprintf(stderr, " iTlsExtern (from MainDebug) = %d\n", iTlsExtern); > } > > int main(void) > { > MainDebug(); > LibDebug(); > > LibInit(2); > > MainDebug(); > LibDebug(); > > return 0; > } > > ----- Makefile > CROSS=x86_64-w64-mingw32- > > .PHONY: all clean > all: prog.exe > clean: > rm -f prog.exe prog.o liblib.dll.a lib.dll lib.o > > prog.exe: prog.o lib.dll > $(CROSS)gcc -std=gnu11 -o prog.exe prog.o \ > -Wl,--add-stdcall-alias -Wl,--export-all-symbols -L. -llib -lpthread > > prog.o: prog.c lib.h > $(CROSS)gcc -std=gnu11 -DLIB_DLLPORT=IMPORT -o prog.o -c prog.c > > lib.dll: lib.o > $(CROSS)gcc -Wl,--out-implib=liblib.dll.a -o lib.dll lib.o \ > -shared -Wl,-hliblib.dll.a -Wl,--add-stdcall-alias > -Wl,--export-all-symbols -lpthread > > lib.o: lib.c lib.h > $(CROSS)gcc -std=gnu11 -DLIB_DLLPORT=EXPORT -o lib.o -c lib.c
The issue here is that you try to mix two concepts here. A thread-local variable can't be exported by dll-export, due its address is mutable for each thread. So it is invalid trying to dllexport such a variable. A valid way of exporting a TLS-variable would be by using a helper-function, which returns the address of the TLS-variable for the calling thread. Regards, Kai ------------------------------------------------------------------------------ Rapidly troubleshoot problems before they affect your business. Most IT organizations don't have a clear picture of how application performance affects their revenue. With AppDynamics, you get 100% visibility into your Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro! http://pubads.g.doubleclick.net/gampad/clk?id=84349831&iu=/4140/ostg.clktrk _______________________________________________ Mingw-w64-public mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
