2013-02-15 11 views
10

Ho un'applicazione che utilizza dlopen() per caricare moduli aggiuntivi. L'applicazione e i moduli sono costruiti su Ubuntu 12.04 x86_64 usando gcc 4.6 ma per i386 arch. I binari vengono quindi copiati su un'altra macchina con esattamente lo stesso sistema operativo e funzionano correttamente.Impossibile caricare altri oggetti con TLS statico

Tuttavia se sono copiati in Ubuntu 12.04 i386 poi alcuni (ma non tutti) i moduli non vengono caricati con il seguente messaggio:

dlopen: cannot load any more object with static TLS 

Ho il sospetto che questo è causato dall'uso di __thread variabili. Tuttavia tali variabili non sono utilizzate nei moduli caricati - solo nel modulo del caricatore stesso.

Qualcuno può fornire ulteriori informazioni, quale può essere la causa?

sto riducendo il numero di __thread variabili e ottimizzazione (con -ftls-model, ecc), sono solo curioso il motivo per cui non funziona su quasi stesso sistema.

+0

Correlato: http://stackoverflow.com/questions/13650740/dlopen-cannot-load-any-more-object-with-static-tls – Wok

risposta

11

Sospetto che ciò sia causato dall'uso di variabili __thread.

Corretto.

Tuttavia tali variabili non vengono utilizzate nei moduli caricati, ma solo nel modulo del caricatore stesso.

errato. È possibile che non si stia utilizzando __thread, ma alcune librerie collegate staticamente al modulo sono che le utilizzano. È possibile confermare questo con:

readelf -l /path/to/foo.so | grep TLS 

quello che può essere il motivo?

Il modulo utilizza -ftls-model=initial-exec, ma dovrebbe utilizzare -ftls-model=global-dynamic. Ciò accade spesso quando (alcuni) il codice collegato a foo.so viene creato senza -fPIC.

Linking codice non -fPIC in una libreria condivisa è impossibile su x86_64, ma è consentita su ix86 (e porta a molti problemi sottili, come questo).

Aggiornamento:

ho 1 modulo compilato senza -fPIC, ma io non impostare TLS-modello a tutti, per quanto mi ricordo il valore di default non è iniziale-exec

  • Potrebbe esserci un solo modello tls per ogni immagine ELF (eseguibile o libreria condivisa).
  • Il modello TLS predefinito è initial-exec per codice non -fPIC.

Ne consegue che se si collega anche un solo non -fPIC oggetto che utilizza __thread in foo.so, quindi foo.so ottiene initial-exec per tutta della sua TLS.

Quindi perché causa problemi: perché se viene utilizzato exec iniziale, il numero di variabili tls è limitato (perché non vengono allocate dinamicamente)?

Corretto.

+0

Non capisco completamente. Ho 1 modulo compilato senza -fPIC (stavo sperimentando con le prestazioni), ma non ho impostato affatto tls-model, per quanto mi ricordo il valore predefinito non è initial-exec? Quindi, perché causa problemi: perché se viene utilizzato exec iniziale, il numero di variabili tls è limitato (perché non vengono allocate dinamicamente)? Ho già risolto i miei problemi riducendo il numero di __thread vars (erano nell'header .h usato in pochi moduli, li ho messi tutti in uno solo) e l'errore è scomparso, ma sono comunque curioso. – queen3

+1

@ queen3 Ho aggiornato la risposta. –

+0

@EmployedRussian 'readelf -l' ->' readelf --dynamic'? –

Problemi correlati