Warum wird davon abgeraten, glibc statisch zu verknüpfen?

Warum wird davon abgeraten, glibc statisch zu verknüpfen?

Die in anderen Antworten angegebenen Gründe sind richtig, aber sie sind nicht der wichtigste Grund.

Der wichtigste Grund, warum die glibc nicht statisch gelinkt werden sollte, ist, dass sie intern extensiv Gebrauch von dlopen macht , um NSS (Name Service Switch)-Module und iconv zu laden Konvertierungen. Die Module selbst verweisen auf C-Bibliotheksfunktionen. Wenn das Hauptprogramm dynamisch mit der C-Bibliothek gelinkt wird, ist das kein Problem. Aber wenn das Hauptprogramm statisch mit der C-Bibliothek gelinkt ist, dlopen muss eine zweite Kopie laden der C-Bibliothek, um die Ladeanforderungen der Module zu erfüllen.

Das bedeutet, dass Ihr "statisch gelinktes" Programm immer noch eine Kopie von libc.so.6 benötigt auf dem Dateisystem vorhanden sein, plus NSS oder iconv oder welche Module selbst auch immer, plus andere dynamische Bibliotheken, die die Module benötigen könnten, wie ld-linux.so.2 , libresolv.so.2 , usw. Dies ist normalerweise nicht das, was Leute wollen, wenn sie Programme statisch verknüpfen.

Es bedeutet auch, dass das statisch gelinkte Programm zwei Kopien der C-Bibliothek in seinem Adressraum hat, und sie könnten sich darum streiten, wessen stdout Puffer verwendet werden, wer sbrk anrufen darf mit einem Argument ungleich Null, so etwas. Es gibt eine Menge Abwehrlogik innerhalb von glibc, um zu versuchen, dass dies funktioniert, aber es wurde nie garantiert zu arbeiten.

Sie denken vielleicht, dass sich Ihr Programm darüber keine Gedanken machen muss, weil es niemals getaddrinfo aufruft oder iconv , aber die Gebietsschemaunterstützung verwendet iconv intern, was beliebigen stdio.h bedeutet Funktion könnte einen Aufruf an dlopen auslösen , und Sie steuern dies nicht, die Umgebungsvariableneinstellungen des Benutzers tun dies.


Das Programm/glibc Die Schnittstelle ist durch POSIX, die C- und C++-Standards und andere standardisiert und dokumentiert. Beispiel:fopen() Funktion verhält sich gemäß dem C-Standard und pthread_mutex_lock() pro POSIX.

Die glibc /kernel-Schnittstelle ist nicht standardisiert. Hat fopen() Verwenden Sie open() unter der Haube? Oder verwendet es openat() ? Oder etwas anderes? Was wird es nächstes Jahr verwenden? Du weißt es nicht.

Wenn der glibc /kernel-Schnittstellenänderungen, ein Programm, das alle Änderungen verwendet, aber glibc statisch verknüpft funktioniert nicht mehr.

Vor über 15 Jahren entfernte Solaris alle statischen Versionen von libc genau aus diesem Grund.

Statische Verlinkung – wo ist das hin?

Bearbeiten:

Die Stabilität der Linux-Kernel-Schnittstelle scheint ernsthaft überschätzt zu werden. Einzelheiten finden Sie unter Änderungen/Ergänzungen der Linux-Kernel-API. Zusammenfassend:


Fehlerkorrekturen in glibc sind nicht in einer statisch gelinkten Anwendung enthalten, wenn Sie glibc aktualisieren, es sei denn, Sie erstellen die Anwendung neu.

Außerdem funktioniert NSS (Name Service Switch) nur, wenn Sie dynamische Verknüpfungen verwenden.