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