2014-01-23 13 views
6

Ich habe eine gemeinsame Bibliothek (libtest.cpp) und ein einfaches Programm (test.cpp). Ich möchte, dass sie eine Thread lokale Variable gVar teilen. Die gemeinsam genutzte Bibliothek ist über LD_PRELOAD verbunden.LD_PRELOAD und Thread lokale Variable

Hier ist mein Code für die gemeinsam genutzte Bibliothek libtest.cpp:

#include<stdio.h> 

__thread int gVar; 

void print_gVar(){ 
    printf("%d\n", gVar); 
} 

Unten ist der Code für test.cpp.

#include<stdio.h> 

__thread int gVar; 

void __attribute__((weak)) print_gVar(); 

int main(){ 
    gVar = 10; 
    print_gVar(); 
    return 0; 
} 

Und ich verwende das folgende Skript, um sie zu kompilieren und auszuführen.

Das erwartete Ergebnis ist 10, da die Zuweisung in test.cpp die gVar in libtest.cpp beeinflusst. Allerdings habe ich nur 0. Es scheint, dass die gVar in libtest.cpp und die gVar in test.cpp nicht verknüpft sind.

habe ich ein paar zusätzliche Tests:

Wenn ich __attribute__((weak)) auf die Erklärung von gVar in eine der Dateien hinzufügen, ist der Ausgang 0.

noch

Wenn ich __thread von beiden Dateien zu entfernen, dann wird das Ergebnis ist 10 (erfolgreich).

Wenn ich extern und zu der Deklaration von gVar in libtest.cpp hinzufügen, wird es Segmentierungsfehler geben.

Ich denke, es muss etwas mit LD_PRELOAD und __thread falsch sein. Aber ich kann nicht herausfinden.

Kann mir jemand sagen, wie ich es schaffen kann? Vielen Dank!

Antwort

5

Dies ist nicht möglich, da Thread-Local-Storage eine Initialisierung pro Thread erfordert.

LD_PRELOAD lädt die Bibliothek, noch bevor die Standardbibliothek geladen wird, wodurch die TLS-Initialisierung fehlschlägt.

Update:

Bitte lesen Sie Abschnitt 2 und 3 von ELF Handling For Thread-Local Storage

+0

Vielen Dank! Könnten Sie mir bitte noch mehr Referenzen geben? – ZillGate

+0

Gern geschehen, nur hinzugefügt. Leider wird nichts speziell für dieses Problem erwähnt, aber Sie sollten sich eine Vorstellung davon machen, wie die TLS-Initialisierung überhaupt funktioniert. – voodooattack

+0

@voodooattack Ich verstehe deine Antwort nicht ganz. Können Sie es ein wenig erläutern, warum es nicht funktioniert? Und implizieren Sie, dass die Bibliothek LD_PRELOADed tls nicht verwenden kann? Das klingt falsch für mich. Viele Szenarien müssen LD_PRELOADed Bibliothek zusammen mit TLS verwenden, nicht wahr? Zum Beispiel https://github.com/jemalloc/jemalloc/issues/937 – Infinite