Come lavorare con le dipendenze di oggetti condivisi (libreria) in Linux

testo della biblioteca su sfondo bianco
Dima Polies/Shutterstock.com

Errore durante il caricamento delle librerie condivise: il temuto errore in cui ogni utente Linux prima o poi si imbatterà. Qualcosa è andato storto con le dipendenze degli oggetti condivisi (le librerie) utilizzate dall’eseguibile. Scopri come risolvere questi problemi e altro ancora!

Che cos’è un? Dipendenza da oggetti condivisi?

Un oggetto condiviso (chiamato anche libreria) è un binario (di solito non direttamente eseguibile) utilizzato da più programmi/applicazioni su un’istanza Linux. Tali librerie sono spesso installate a livello di sistema operativo e sono condivise (da cui il nome oggetto condiviso o libraries) per l’utilizzo da parte di una o più (e anche molte) applicazioni eseguibili direttamente.

Ad esempio, un programma che prevede la compressione di file potrebbe richiedere la libreria bz2 (bzip2) libbz2.so.1.0 fare così. Il termine biblioteca è più spesso utilizzato nei circoli Linux ed è il gergo preferito tra i professionisti, anche se oggetto condiviso (e libreria condivisa) sono entrambi tecnicamente corretti. Interessante notare anche che il .so l’estensione del nome del file utilizzata in molte librerie sta per oggetto condiviso!

Un eseguibile può avere zero, una o molte librerie su cui si basa. Meno librerie, più avanti (quando si aggiorna il sistema operativo, ad esempio) sarà la compatibilità. Maggiore è il numero di librerie, maggiore è la possibilità che prima o poi si interrompa una certa dipendenza dalla libreria. Questo è anche il motivo per cui i fornitori di applicazioni a volte decidono di rilasciare statically compiled binaries piuttosto che dynamically compiled binaries.

La differenza tra binari compilati staticamente e dinamicamente è semplice ma ha conseguenze di vasta portata. Un binario compilato staticamente ha le librerie (disponibili sul sistema dello sviluppatore al momento della compilazione) compilate nel binario/eseguibile risultante. Un binario compilato dinamicamente utilizzerà le librerie installate, disponibili e condivise sul sistema dell’utente.

Come puoi vedere immediatamente, ciò richiederebbe all’utente di installare tali dipendenze richieste, a meno che non si occupi delle stesse nel sistema operativo o nel sistema di gestione dei pacchetti del fornitore dell’applicazione e nei dettagli. Questo è il motivo per cui eseguire un semplice comando come sudo apt install ...some_app... spesso produrrà una serie di altre cose correlate (cioè le librerie richieste) da co-installare allo stesso tempo.

Sia la compilazione statica che quella dinamica hanno vantaggi e svantaggi. Ad esempio, se usi la compilazione statica e una libreria che hai incluso nel tuo pacchetto software (dal punto di vista di un fornitore di software) ora ha un bug di sicurezza o un aggiornamento critico, probabilmente significa che devi rilanciare il tuo pacchetto software, anche se non è cambiato nulla nel tuo codice.

Ma poi di nuovo, affidarsi all’utente per installare librerie, specialmente per programmi complessi, o quando è richiesta l’autocompilazione del software, con la consapevolezza che gli utenti finali spesso lottano con queste cose, non è l’ideale. È un’area complessa e la questione è stata discussa spesso.

Ai fini di questo articolo, esamineremo le librerie condivise in relazione a un programma che è stato compilato dinamicamente, come spesso accade con programmi/eseguibili/strumenti del sistema operativo. Con i programmi compilati staticamente (che sono meno comuni), è altamente improbabile che venga visualizzato un errore come “Errore durante il caricamento delle librerie condivise”, poiché le librerie sono incluse nell’eseguibile a meno che il programma non sia in parte dinamico e includa solo un set limitato di nelle librerie statiche.

Errore durante il caricamento delle librerie condivise!

Passiamo a radice modalità per un po’ (usando sudo su) ed esplora come funzionano le librerie condivise quando si tratta di uno strumento come /usr/bin/zip che è incluso o installabile con le principali distribuzioni Linux.

Usare ldd in Linux

Qui, abbiamo cambiato directory in /usr/bin e verificato se il zip programma/binario/eseguibile è presente. Trovandolo presente, abbiamo quindi verificato la versione invocandola con --version e prendendo solo le prime due righe dell’output convogliando l’output (usando |) per evitare il lungo output dato altrimenti.

Infine, abbiamo usato il ldd tool (un programma che stampa le dipendenze degli oggetti condivisi) per vedere quali librerie richiede l’eseguibile. Come possiamo vedere, il programma richiede quattro librerie condivise. L’elenco delle librerie richieste è solitamente nel formato della libreria richiesta, seguito da un percorso in cui è già stata trovata la libreria nominata.

Per alcune librerie di livello superiore o speciali del sistema operativo (come linux-vdso.so.1), non viene mostrato tale percorso. Tuttavia, finché non viene visualizzato alcun errore per nessuna voce, sai che va bene e disponibile (o preferibile). Infatti, linux-vdso.so.1 è uno speciale oggetto/libreria virtuale condiviso inserito in ogni processo dal kernel Linux, che non ha un file fisico su disco per lo stesso. È lì per rendere più efficienti le chiamate di sistema.

Quindi, rompiamo un po’ le cose e rinominiamo una delle librerie richieste in modo che non possa più essere scoperta automaticamente dal binario:

Errore durante il caricamento delle librerie condivise e della libreria mancante

Come puoi vedere, qui abbiamo rinominato/spostato il file da /lib/x86_64-linux-gnu/libbz2.so.1.0 per /lib/x86_64-linux-gnu/libbz2.so.1.0.NOT_PRESENT. Questo ha rotto la nostra applicazione zip e quando proviamo a eseguirla, otteniamo il temuto error while loading shared libraries errore. Tuttavia, guardando un po’ più da vicino, il messaggio di errore è piuttosto descrittivo:

zip: error while loading shared libraries: libbz2.so.1.0: cannot open shared object file: No such file or directory

Un tecnico IT esperto esaminerà sempre attentamente tutti i registri e l’output/informazioni del programma presentate a lui o lei prima di effettuare una chiamata su un problema. Sarebbe utile anche qui, poiché il file richiesto è chiaramente mostrato, libbz2.so.1.0, e anche il problema è chiaramente mostrato. c’è No such file or directory. In altre parole, libbz2.so.1.0 manca!

Possiamo anche verificare lo stesso con ldd, come si può vedere nell’immagine sopra. Un chiaro libbz2.so.1.0 => not found ci aiuta a sapere cosa sta succedendo. Una volta compreso chiaramente come i binari compilati dinamicamente (la maggior parte dei binari nel sistema operativo sono compilati in questo modo) caricano e richiedono librerie e come vedere se ne manca uno (o se ne viene informato tramite il messaggio di errore), le cose non non sembra più così complicato.

Inoltre, una volta che conosciamo il nome della libreria richiesta, una rapida ricerca nel tuo motore di ricerca preferito mostrerà il pacchetto aggiuntivo da installare (o reinstallare) per ottenere il nome della libreria richiesto. Molto spesso, il nome del pacchetto può anche essere interpretato direttamente dal nome della libreria. Tuttavia, in questo caso, il nome della libreria di runtime è un po’ sfalsato.

Esistono due tipi di librerie: librerie di runtime e librerie di sviluppo. In questo caso, il nome del pacchetto che contiene il libbz2.so.1.0 la biblioteca è probabile bzip2, e il tentativo di disinstallazione probabilmente danneggerebbe vari altri elementi, come si può notare da un lungo elenco di programmi che verranno rimossi se si tenta di disinstallare o eliminare il bzip2 pacchetto.

Il secondo tipo di libreria è una libreria di sviluppo. Questi sono spesso necessari quando si tenta di compilare programmi e sono spesso ancora più strettamente correlati ai nomi dei file di libreria effettivi. Ad esempio, in Ubuntu, prendi semplicemente il nome della libreria e aggiungi -dev. Ad esempio, se volessimo installare il pacchetto di sviluppo relativo al libbz2.so.1.0 pacchetto, potremmo guardare all’installazione libbz2-dev:

Installazione di una libreria di sviluppo

Considerando che questa libreria di sviluppo non è direttamente correlata alla nostra libbz2.so.1.0 libreria runtime, è utile conoscere la sintassi dei nomi della maggior parte dei nomi dei pacchetti di sviluppo in Ubuntu (prefisso di lib e suffisso di -dev con il nome della libreria tra quelli) per ogni volta che è richiesta una determinata libreria di sviluppo (che è spesso necessaria durante la compilazione del software).

Inoltre, supponi che una libreria in qualche modo si sia rotta. In tal caso, una delle soluzioni rapide più semplici è eliminare la libreria sudo apt purge your_library_name comando (che eliminerebbe completamente la libreria/programma passato), seguito da una reinstallazione utilizzando il comando sudo apt install your_library_name comando.

E quando ti imbatti in una situazione simile a quella sopra, in cui la disinstallazione della libreria di runtime richiede la disinstallazione/eliminazione del programma principale e in cui tale eliminazione/rimozione è una parte troppo grande del sistema operativo o influenzerebbe troppe altre cose, tu può invece utilizzare un’opzione di reinstallazione:

Reinstallare un'applicazione o una libreria

sudo apt reinstall bzip2

Tuttavia, non è sempre così facile, pur conoscendo quanto sopra (e soprattutto la convenzione di denominazione in termini di aggiunta -dev) aiuta enormemente nella risoluzione dei problemi e spesso risolve il problema direttamente.

Aiuta molto anche sapere come le librerie possono essere controllate usando ldde, infine, capire che una libreria è solo un eseguibile (anche se non direttamente) .so file che vive in una sottodirectory di /lib o in /usr/lib o altre directory simili.

A volte, le librerie e/o i pacchetti sono in conflitto tra loro, o alcuni pacchetti richiedono determinate versioni di librerie, o alcune librerie richiedono altre librerie, a versioni specifiche stesse. Sì, diventa un po’ complesso. È anche piuttosto facile, quando diventa così complesso, incasinare leggermente un sistema. A volte, è persino possibile interrompere completamente l’installazione di un sistema operativo a causa dello spostamento di una libreria troppo importante, ecc.

Spesso, è un po’ più sicuro creare un collegamento simbolico (un collegamento virtuale con un determinato nome file, che fa riferimento/collega a un altro file esistente o un altro collegamento simbolico stesso, che a sua volta punta a un file reale) per una libreria mancante in una versione precedente, ad esempio e puntando quel collegamento simbolico all’ultima versione installata. Non sempre funziona, ma nel caso in cui fallisca, il collegamento simbolico può essere rimosso, si spera in modo più sicuro (supponendo che non esistesse in precedenza alcun collegamento simbolico o file con lo stesso nome).

Il modo migliore per risolvere questi problemi più complessi è provare sempre un apt (o uno strumento di gestione dei pacchetti simile sul tuo sistema operativo) -prima soluzione basata. A questo punto, vorrai anche leggere come usare dkpg per correggere apt, poiché ti mostra un modo più granulare per gestire i pacchetti (sebbene fai attenzione, poiché un maggiore controllo comporta maggiori responsabilità!).

Se tutto il resto fallisce, prova a creare un collegamento simbolico o anche ad aggiungere manualmente il file della libreria. (Assicurati tre volte che qualsiasi file scaricato sia privo di virus, ad esempio, controllandolo con VirusTotale, ed è sempre meglio usare i repository forniti dal fornitore di Linux per scaricare i binari.)

In extremis, potresti anche essere in grado di trovare una libreria in un sistema operativo Linux vicino. Ad esempio, un eseguibile di Ubuntu verrà eseguito su Mint e viceversa. Copiare una libreria da un altro PC che hai è anche un approccio praticabile a volte.

Avvolgendo

La gestione dettagliata delle biblioteche è un’abilità che richiede una vita per essere imparata. È quasi un’arte. Questo articolo ha fornito le informazioni di base, il know-how e gli strumenti da utilizzare e ha elencato alcuni suggerimenti per la risoluzione dei problemi più avanzati per quando le cose diventano oscure e, prima o poi, lo faranno se sei un utente frequente di Linux che installa regolarmente pacchetti.

Quando vedrai l’errore “Errore durante il caricamento delle librerie condivise” sulla tua macchina Linux, sarai meglio attrezzato per capire da dove potrebbe derivare il problema usando uno strumento come ldd, come spiegato in questo articolo. Abbiamo anche esaminato i binari statici rispetto a quelli compilati dinamicamente e come le librerie condivise o integrate si adattano e funzionano con entrambi.

Se ti è piaciuto questo articolo, ti potrebbe piacere leggere anche l’articolo su dpkg linkato sopra e come aggiungere i repository Universe, Multiverse e Restricted in Ubuntu.