mi sono imbattuto in questo errore io stesso, e mentre indaga, mi è venuto su un 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.
Guardando /usr/include/elf.h
, abbiamo:
/* Values of `d_un.d_val' in the DT_FLAGS entry. */
...
#define DF_STATIC_TLS 0x00000010 /* Module uses the static TLS model */
Quindi è necessario verificare se DF_STATIC_TLS
è impostato nella voce DT_FLAGS
della libreria condivisa.
Per provare le cose, ho creato un semplice pezzo di codice utilizzando filo di archiviazione locale:
static __thread int foo;
void set_foo(int new) {
foo = new;
}
ho poi compilato due volte con i due diversi modelli di archiviazione locale di thread:
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
E sicuro abbastanza, posso vedere una differenza tra le due librerie usando readelf
:
$ readelf --dynamic tls-initial-exec.so
Dynamic section at offset 0xe00 contains 25 entries:
Tag Type Name/Value
...
0x000000000000001e (FLAGS) STATIC_TLS
La versione tls-global-dynamic.so
non disponeva di una voce DT_FLAGS
, presumibilmente perché non disponeva di alcun flag impostato. Quindi dovrebbe essere abbastanza facile creare uno script usando readelf
e grep
per trovare le librerie interessate.
fonte
2014-04-11 03:51:04
Grazie mille! Bella risposta. Ho anche trovato 'readelf -l library | grep TLS' utile. Questo indica se c'è spazio per lo stoccaggio di qualsiasi thread. Si scopre che qualsiasi cosa con TLS utilizza anche uno slot DTV (e quindi può bloccare successivamente oggetti STATIC_TLS dal caricamento), ma se si caricano prima gli oggetti STATIC_TLS, quelli non-intial-exec usano un altro metodo e non prendono uno slot. – robince