2015-12-10 39 views
13

'da "normal sembol için geçersiz iş parçacığı yerel başvuru" hatası Bağlama sırasında oluşan garip bir sorun var.TLS değişken

struct Foo { static __thread int x; } 

Ve plugin.cpp değişken olduğunu başvuran bir kaynak dosyası:

$CXX -stdlib=libc++ -std=c++11 -fvisibility=hidden -fPIC -o plugin.cpp.o -c plugin.cpp 
:

#include "foo.hpp" 
void bar() { int y = Foo::x; } 

O ince derler

Ben şu tanımı foo.hpp içeren bir başlık dosyası var

Ancak dinamik bir librar olarak bağlanmaya çalıştığımda y:

$CXX -stdlib=libc++ -std=c++11 -fvisibility=hidden -dynamiclib -Wl,-undefined,dynamic_lookup -o libext.dylib ext.cpp.o 

alıyorum:

ld: __ZN3Foo1xE mimarisi x86_64 için düzenli sembolü yasadışı iş parçacığı yerel değişken referans

LLVM baytkodu derleyici doğru görüyor ima Ancak

TLS değişkeni olarak Foo::x.

$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 
} 

Bu bağlayıcı sorununa ne neden olabilir ve bir geçici çözüm var mı? Bununla ilgili herhangi bir hata raporu bulamıyorum.

Notlar:

  • Bu tamamen Apple LLVM 7.0.0
  • kullanıyor ben herhangi bir sorun OS X

DÜZENLEME üzerinde gcc 5 veya gcc 4.9.3 kullanarak bağlama var Genel (statik sınıf yerine) değişkenine başvururken aynı sorun vardır.

__thread yerine thread_local kullanıldığında, bu iyi çalışır, ancak thread_local Xcode ile birlikte gelen LLVM sürümü ile çalışmaz.

+0

Eğer Foo :: x' yerine global bir değişken yaparsanız ne olur? Bu çalışırsa, global olarak bırakabilir veya foo.cpp'ye foo.cpp'de foo'da statik bir alıcı işleviyle yerel (statik veya anonim ad alanı) olabilir. Ben sadece tahmin ediyorum; Belki derleyicinin statik __ üye üye değişkenleri ile ilgili bir sorunu vardır. – 1201ProgramAlarm

+0

@ 1201ProgramAlarm: Bunu soruya koymalıydım. Küresel bir değişken kullanmak aynı sorunu verir. Tabii ki, kullanım durumu eşdeğerini yapmak için, beyan, extern __thread int my_global; ' –

+0

Sadece x değişkenini ilan ettiniz, bunun için tanımımızı gösteriniz. Dolardan çöreklere, tanımada üşümeyi unuttun. Ya da tamamen unuttun ve berbat bir bağlayıcı tanıdım. –

cevap

0

Yürütülebilir dosya formatı (MACH-O inanıyorum) iş parçacığı Yerel depolama alanına izin vermiyor. Kıçındaki bir acı. İş parçacığı kitaplığının bellek ayırmasında boşluk oluşturmanız ve oradaki iş parçacığı yerel değişkenlerini gizlemeniz gerekir. Onun çok çok karanlık.

+0

Bunu tarif etmesi gereken bir bağlantı. https://software.intel.com/en-us/forums/intel-c-compiler/topic/498638 –