ich in diesen Fehler selbst lief, und während es zu untersuchen, kam ich auf einem mailing list post with this info:
If you link a shared object containing IE-model access relocs, the object will have the DF_STATIC_TLS flag set. By the spec, this means that dlopen might refuse to load it.
bei /usr/include/elf.h
suchen, haben wir:
/* Values of `d_un.d_val' in the DT_FLAGS entry. */
...
#define DF_STATIC_TLS 0x00000010 /* Module uses the static TLS model */
Sie müssen also, wenn DF_STATIC_TLS
testen wird im Eintrag DT_FLAGS
der gemeinsam genutzten Bibliothek festgelegt.
Dinge zu testen, habe ich ein einfaches Stück Code Thread-Lokalspeicher mit:
static __thread int foo;
void set_foo(int new) {
foo = new;
}
ich es dann mit den beiden anderen Thread lokalen Speichermodellen zweimal zusammengestellt:
gcc -ftls-model=initial-exec -fPIC -c tls.c -o tls-initial-exec.o
gcc -shared tls-initial-exec.o -o tls-initial-exec.so
gcc -ftls-model=global-dynamic -fPIC -c tls.c -o tls-global-dynamic.o
gcc -shared tls-global-dynamic.o -o tls-global-dynamic.so
Und sicher genug ist, kann ich einen Unterschied zwischen den beiden Bibliotheken sehen readelf
mit:
$ readelf --dynamic tls-initial-exec.so
Dynamic section at offset 0xe00 contains 25 entries:
Tag Type Name/Value
...
0x000000000000001e (FLAGS) STATIC_TLS
Die tls-global-dynamic.so
-Version hatte keinen DT_FLAGS
-Eintrag, vermutlich weil keine Flags gesetzt waren. Es sollte also ziemlich einfach sein, ein Skript zu erstellen, das readelf
und grep
verwendet, um betroffene Bibliotheken zu finden.
Vielen Dank! Gute Antwort. Ich fand auch 'readelf -l library | grep TLS' nützlich. Dies zeigt an, ob überhaupt ein Thread-Loca-Speicher vorhanden ist. Es stellt sich heraus, dass alles mit TLS auch einen DTV-Steckplatz verwendet (und somit spätere STATIC_TLS-Objekte vom Laden blockieren kann), aber wenn Sie zuerst die STATIC_TLS-Objekte laden, verwenden die Nicht-Anfangs-Exec-Methoden eine andere Methode und nehmen keinen Slot. – robince