C ++ erzwingt das Entladen der gemeinsam genutzten Bibliothek

8

Ich versuche eine Anwendung zu erstellen, die eine gemeinsam genutzte Bibliothek mehrmals neu lädt. Aber zu irgendeinem Zeitpunkt schlägt dlmopen mit Fehler

fehl

/usr/lib/libc.so.6: cannot allocate memory in static TLS block

Hier ist der minimale Code, der dieses Problem reproduziert:

%Vor%

Und leere lib.cpp, kompiliert mit

%Vor%

Aktualisieren

Es scheint, dass es sogar mit einem Thread abstürzt. Die Frage ist: Wie kann ich eine Bibliothek entladen oder eine Zerstörung von unbenutzten Namespaces erzwingen, die mit LM_ID_NEWLM erstellt wurden?

    
Ilya Lukyanov 08.06.2016, 22:12
quelle

2 Antworten

2

Es gibt eine integrierte Beschränkung für die Anzahl der Linkmap-Namespaces, die für einen Prozess verfügbar sind. Dies ist im Kommentar eher schlecht dokumentiert:

  

Die glibc-Implementierung unterstützt maximal 16 Namespaces

in der Manpage.

Sobald Sie einen Linkmap-Namespace erstellt haben, können Sie ihn nicht mehr über APIs "löschen". Das ist genau so, wie es entworfen wurde, und es gibt keine echte Möglichkeit, das zu umgehen, ohne die glibc-Quelle zu bearbeiten und ein paar Haken hinzuzufügen.

Die Verwendung von Namespaces zum erneuten Laden einer Bibliothek lädt die Bibliothek nicht wirklich neu - Sie laden einfach eine neue Kopie der Bibliothek. Dies ist einer der Anwendungsfälle der Namespaces - wenn Sie versucht haben, dlopen dieselbe Bibliothek mehrmals zu verwenden, erhalten Sie denselben Handle für dieselbe Bibliothek. Wenn Sie jedoch die zweite Instanz in einem anderen Namespace laden, erhalten Sie nicht das gleiche Handle. Wenn Sie das Neuladen durchführen möchten, müssen Sie die Bibliothek mit dlclose entladen, wodurch die Bibliothek entladen wird, sobald die letzte verbleibende Referenz auf die Bibliothek freigegeben wurde.

Wenn Sie versuchen möchten, eine Bibliothek zwangsweise zu entladen, können Sie versuchen, mehrere dlclose -Aufrufe auszugeben, bis sie entladen werden. Wenn Sie jedoch nicht wissen, was die Bibliothek getan hat (z. B. erzeugte Threads), besteht in diesem Fall möglicherweise keine Möglichkeit, einen Absturz zu verhindern.

    
Petesh 11.01.2017, 09:20
quelle
0

Ältere glibc-Versionen könnten einige Fehler haben, die damit zusammenhängen:

Ссылка   Ссылка

Welche Version verwenden Sie? Versuchen Sie es mit einer neueren glibc-Version, Ihr Code funktioniert ziemlich gut auf meinem Computer (glibc 2.23).

    
spektom 10.01.2017 10:26
quelle

Tags und Links