Ho uno strano problema che si verifica durante il collegamento.Errore "thread-riferimento locale locale a simbolo normale" su una variabile TLS
Ho un file di intestazione che contiene la seguente definizione foo.hpp
:
struct Foo { static __thread int x; }
E un file di origine che fa riferimento tale variabile plugin.cpp
:
#include "foo.hpp"
void bar() { int y = Foo::x; }
compila bene con:
$CXX -stdlib=libc++ -std=c++11 -fvisibility=hidden -fPIC -o plugin.cpp.o -c plugin.cpp
Ma quando provo a collegarmi come una librer dinamica y:
$CXX -stdlib=libc++ -std=c++11 -fvisibility=hidden -dynamiclib -Wl,-undefined,dynamic_lookup -o libext.dylib ext.cpp.o
ottengo:
ld: variabile di riferimento illegale filo all'ora simbolo regolare __ZN3Foo1xE per x86_64
Tuttavia il bytecode llvm implica che il compilatore sia correttamente vedendo Foo::x
come variabile TLS.
$CXX -stdlib=libc++ -std=c++11 -fvisibility=hidden -fPIC -S -emit-llvm -o -
... omitted
@_ZN3Foo1xE = external thread_local global i32
... omitted
; Function Attrs: nounwind ssp uwtable
define hidden void @_Z3barv() #0 {
%y = alloca i32, align 4
%1 = load i32* @_ZN3Foo1xE, align 4
store i32 %1, i32* %y, align 4
ret void
}
Cosa potrebbe causare questo problema del linker e c'è una soluzione alternativa? Non riesco a trovare alcuna segnalazione di bug relativa a questo.
Note:
- Questo è puramente usando la LLVM di Apple 7.0.0
- non ho problemi di collegamento utilizzando gcc 5 o 4.9.3 gcc su OS X
EDIT Lo stesso problema esiste quando si fa riferimento a una variabile globale (anziché di classe statica).
Quando uso thread_local
in sostituzione di __thread
, funziona correttamente, tuttavia thread_local
non funziona con la versione di LLVM fornita con Xcode.
Cosa succede se invece si rende 'Foo :: x' una variabile globale? Se funziona, puoi lasciarlo globale, oppure farlo locale (namespace statico o anonimo) su foo.cpp con una funzione getter statica in 'Foo'. Sto solo indovinando; forse il compilatore ha un problema con le variabili dei membri __thread statiche. – 1201ProgramAlarm
@ 1201ProgramAlarm: avrei dovuto metterlo nella domanda. L'utilizzo di una variabile globale produce lo stesso identico problema. Naturalmente, per rendere l'equivalente del caso d'uso, la dichiarazione è 'extern __thread int my_global;' –
Hai solo dichiarato la variabile x, mostraci la definizione per esso. Dollari alle ciambelle, hai dimenticato __thread nella definizione. Oppure l'hai dimenticato completamente e hai ottenuto una diagnostica pessima per il linker. –