Perché ci sono due diversi tipi di collegamento, vale a dire statico e dinamico?

5

Sono stato morso per l'ennesima volta da una mancata corrispondenza tra una build e un ambiente di distribuzione. L'ambiente di costruzione aveva libruby.so.2.0 e l'ambiente di distribuzione aveva libruby.a . Un rubino è stato creato con RVM, l'altro è stato creato con ruby-build . Il motivo per cui mi sono imbattuto in un problema era dovuto al fatto che lo zookeeper è stato compilato in un ambiente di build con la libreria condivisa ma l'ambiente di distribuzione aveva solo la libreria statica.

In tutti gli anni in cui ho scritto codice dell'applicazione non ho mai desiderato una volta che i binari stavo usando dove collegato agli oggetti condivisi. Qual è la ragione per cui la dicotomia persiste fino ad oggi sui sistemi operativi moderni?

    
posta davidk01 06.06.2014 - 02:45
fonte

3 risposte

7

Static

Con un'applicazione collegata staticamente, tutto ciò che è necessario per eseguire l'applicazione fa parte dell'applicazione stessa. Dipende da nient'altro.

Se c'è un errore fatale in una libreria collegata dinamicamente, non "importa".

Se la versione collegata dinamicamente di una libreria che utilizza non è presente (qualcuno ha rimosso per sbaglio /lib su un sistema unix?) non gli interessa.

Non richiede installazioni aggiuntive di librerie da eseguire su qualsiasi piattaforma compatibile binaria. Scarica l'app e puoi eseguirla.

Esiste un'intera directory di applicazioni collegate staticamente su ogni sistema Unix in /sbin che sono garantite per funzionare sempre anche se parti significative del sistema sono altrimenti rotte o mancanti. %codice%? %codice%? %codice%? %codice%? %codice%? %codice%? Questi sono probabilmente tutti in reboot in modo che, anche se le librerie sono mancanti o danneggiati (o non montati perché sono su un file system di rete ...) è comunque possibile eseguire questi comandi per ottenere il sistema di lavoro (e montare che in rete file system con le librerie che stai cercando).

Storia vera: un sysadmin molti anni fa, quando un disco rigido da 80 megabyte era grande, cercava un po 'di spazio. Le compilazioni standard includevano informazioni di debug / simboli e richiedevano alcuni kilobyte in ciascun binario. Così, ha trovato ogni eseguibile sul sistema e corse strip su di esso. Sapevi che le librerie condivise sono "eseguibili" su molti sistemi? Rimuovendo da loro le informazioni sui simboli impedisce a qualsiasi cosa di collegarsi dinamicamente a loro ... oops. Le uniche cose che funzionano dove quelle in / sbin. Fortunatamente, ce n'era abbastanza che era in grado di montare l'altro sistema dello stesso tipo e copiare le librerie condivise sul sistema incasinato ...

Dinamico

Vuoi aggiornare una libreria? Nessun problema. Basta mettere la libreria nel posto giusto e tutto va bene. Sì, è un po 'semplicistico, ma è l'idea.

$ ldd /bin/date
  linux-vdso.so.1 =>  (0x00007fff6ffff000)
  librt.so.1 => /lib64/librt.so.1 (0x00007f54ba710000)
  libc.so.6 => /lib64/libc.so.6 (0x00007f54ba384000)
  libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f54ba167000)
  /lib64/ld-linux-x86-64.so.2 (0x00007f54ba919000)

Quelle sono tutte librerie che sono già state caricate da qualche parte che non devi avere nella tua applicazione. Ci possono essere dei risparmi nella dimensione dello spazio del disco perché non è necessario inserire una copia completa di libc o di qualsiasi altra libreria come parte della tua applicazione.

Il patch di sistema diventa più facile. Invece di dover spingere fuori una patch per tutto in / bin perché qualcosa è cambiato (è necessario fare questo per / sbin), basta spingere fuori un nuovo oggetto libreria condivisa e aggiornare la catena di collegamento simbolico in / lib.

Diventa possibile sostituire le sostituzioni. Basta fornire la stessa API e i simboli, rilasciare la nuova libreria e aggiornare la catena di collegamenti simbolici e tutto dovrebbe essere buono.

Su un sistema che esegue più processi (quasi tutti in questi giorni ... ma era una distinzione significativa in passato) le librerie statiche significavano che ogni applicazione in esecuzione aveva una copia completa delle sue librerie che occupavano risorse di memoria. Le librerie condivise indicano che possono semplicemente puntare allo stesso punto nella memoria già caricata.

Il collegamento statico di un'applicazione può essere considerato un lavoro derivato delle librerie. Questo diventa un problema con il software GPL. Ci sono opinioni divergenti su se il collegamento dinamico di una libreria con licenza GPL crea un lavoro derivato.

Il collegamento dinamico consente plug-in. L'applicazione carica i plugin e chiama dinamicamente le funzioni disponibili.

Più lingue possono utilizzare le stesse convenzioni di chiamata e chiamare una libreria dinamica. Guarda qui per esempio un esempio: il collegamento dinamico significa che Clojure, Scala, Groovy, ecc. Con il collegamento dinamico possono usare tutte le stesse librerie condivise. In alternativa, guarda tutte le diverse lingue che possono richiamare un file .DLL su Windows.

Lettura correlata:

risposta data 06.06.2014 - 04:56
fonte
3

Per me, la risposta è molto semplice: risparmiare risorse come lo spazio. Se tutte le applicazioni N su un sistema hanno bisogno della libreria X e tutte collegano staticamente questa libreria ai loro eseguibili, allora c'è (N - 1) (dimensione di X) byte che stai sprecando.

Il motivo per cui il collegamento statico è sopravvissuto affatto è precisamente perché non esiste un sistema che possa garantire che tutte le applicazioni trovino installate le librerie di cui hanno bisogno, nella versione di cui hanno bisogno, allo stesso tempo (vedi diavolo di dipendenza ).

Molte soluzioni sono state provate: conservare librerie con versioni, gestori di pacchetti intelligenti, persino macchine virtuali sono un modo per mettere un livello di riferimento indiretto tra l'applicazione e il sistema "come è adesso". Ognuno di questi ha portato al suo inferno: DLL inferno, RPM inferno e JAR inferno.

L'unico modo a prova di proiettile di distribuire un eseguibile su un'altra macchina è che contiene tutto ciò che deve essere eseguito. Cioè, sprecando risorse.

    
risposta data 06.06.2014 - 11:59
fonte
1

Ci sono vantaggi per ognuno, come nel caso di praticamente tutto nello sviluppo del software.

Dire che sto sviluppando un'applicazione per Windows, che implica una sorta di funzionalità crittografica. Perché quelle funzioni sono complicate, e rotolare le tue è quasi sempre una cattiva idea, io invece uso le librerie fornite dalla piattaforma Windows.

Fai finta che dopo un po 'venga rivelato un brutto bug nelle librerie di Windows, che provoca l'uccisione dei tuoi animali domestici se visiti la pagina web sbagliata.

Se si collega dinamicamente la propria applicazione alle librerie, è possibile effettuare un aggiornamento alla piattaforma e il software può essere riparato dalla sua vulnerabilità senza fare nulla. L'aggiornamento di Windows può risolvere i tuoi problemi.

Se leghi staticamente la tua applicazione alle librerie, dovresti ricompilare una versione aggiornata del tuo software, e distribuirla ai tuoi utenti, e sentire il senso di colpa di tutti i cuccioli uccisi mentre te ne vai in giro.

Lo stesso principio vale per altre piattaforme e librerie.

Inoltre, il collegamento dinamico offre la possibilità di avere cose come i plugin. Puoi anche aggiornare le librerie condivise mentre un'applicazione le sta utilizzando e utilizzare le nuove librerie una volta riavviata l'applicazione.

Questi vantaggi sono il motivo per cui abbiamo collegamenti dinamici.

    
risposta data 06.06.2014 - 03:28
fonte

Leggi altre domande sui tag