2015-12-10 22 views
13

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.

+0

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

+0

@ 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;' –

+0

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. –

risposta

0

Formato file eseguibile delle mele (MACH-O credo) non consente l'archiviazione locale dei thread. È un dolore nel culo. È necessario creare spazio nell'allocazione di memoria della libreria di threading e nascondere le variabili locali del thread. È molto molto oscuro.

+0

Un link che dovrebbe descrivere questo. https://software.intel.com/en-us/forums/intel-c-compiler/topic/498638 –

Problemi correlati