Ich versuche eine Anwendung zu erstellen, die eine gemeinsam genutzte Bibliothek mehrmals neu lädt. Aber zu irgendeinem Zeitpunkt schlägt dlmopen
mit Fehler
/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% 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?
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.
Tags und Links c++ linux shared-libraries