102.3 Lekcija 1
Sertifikat: |
LPIC-1 |
---|---|
Verzija: |
5.0 |
Tema: |
102 Linux instalacija i upravljanje paketima |
Cilj: |
102.3 Upravljanje dijeljenim bibliotekama |
Lekcija: |
1 od 1 |
Uvod
U ovoj lekciji ćemo raspravljati o dijeljenim bibliotekama, također poznatim kao dijeljeni objekti: dijelovima kompajliranog koda za višekratnu upotrebu, poput funkcija ili klasa, koje se stalno koriste od strane različitih programa.
Za početak ćemo objasniti šta su dijeljene biblioteke, kako ih identificirati i gdje se nalaze. Zatim ćemo ući u to kako konfigurisati njihove lokacije za pohranu. Na kraju ćemo pokazati kako tražiti zajedničke biblioteke o kojima zavisi određeni program.
Koncept dijeljenih biblioteka
Slično svojim fizičkim kolegama, softverske biblioteke su kolekcije koda koji su namijenjeni da ih koriste mnogi različiti programi; baš kao što fizičke biblioteke čuvaju knjige i druge resurse koje će koristiti mnogi različiti ljudi.
Da biste napravili izvršnu datoteku iz izvornog koda programa, neophodna su dva važna koraka. Prvo, kompajler pretvara izvorni kod u mašinski kod koji je pohranjen u takozvanim objektivnim datotekama. Drugo, linker kombinuje objektne fajlove i povezuje ih sa bibliotekama kako bi generisao konačnu izvršnu datoteku. Ovo povezivanje se može izvršiti _statički ili dinamički. Ovisno o tome koju metodu koristimo, govorit ćemo o statičkim bibliotekama ili, u slučaju dinamičkog povezivanja, o dijeljenim bibliotekama. Hajde da objasnimo njihove razlike.
- Statičke biblioteke
-
Statička biblioteka se spaja s programom u vrijeme povezivanja. Kopija koda biblioteke je ugrađena u program i postaje njegov dio. Dakle, program nema ovisnosti o biblioteci u vrijeme izvođenja jer program već sadrži kod biblioteke. To što nema zavisnosti može se posmatrati kao prednost jer ne morate da brinete o tome da li su korištene biblioteke uvek dostupne. S druge strane, statički povezani programi su teži.
- Dijeljene (ili dinamičke) biblooteke
-
U slučaju dijeljenih biblioteka, linker jednostavno vodi računa o tome da program ispravno referencira biblioteke. Linker, međutim, ne kopira nijedan bibliotečki kod u programsku datoteku. Međutim, u vrijeme izvođenja, dijeljena biblioteka mora biti dostupna da bi zadovoljila ovisnosti programa. Ovo je ekonomičan pristup upravljanju sistemskim resursima jer pomaže u smanjenju veličine programskih datoteka i samo jedna kopija biblioteke se učitava u memoriju, čak i kada je koristi više programa.
Konvencije o imenovanju datoteka dijeljenih objekata
Ime dijeljene biblioteke, također poznato kao sonname, slijedi obrazac koji se sastoji od tri elementa:
-
Naziv biblioteke (obično sa prefiksom
lib
) -
so
(što znači “dijeljeni objekt”) -
Broj verzije biblioteke
Evo primjera: libpthread.so.0
Za razliku, nazivi statičkih biblioteka završavaju na .a
, e.g. libpthread.a
.
Note
|
Budući da datoteke koje sadrže dijeljene biblioteke moraju biti dostupne kada se program izvršava, većina Linux sistema sadrži dijeljene biblioteke. Pošto su statičke biblioteke potrebne samo u namjenskoj datoteci kada je program povezan, one možda neće biti prisutne na sistemu krajnjeg korisnika. |
glibc
(GNU C library) je dobar primjer dijeljene (zajedničke) biblioteke. Na Debian GNU/Linux 9.9 sistemu, njegova datoteka se zove libc.so.6
. Takva prilično opšta imena datoteka su obično simboličke veze (linkovi) koje upućuju na stvarnu datoteku koja sadrži biblioteku, čije ime sadrži tačan broj verzije. U slučaju glibc
, ova simbolična veza izgleda ovako:
$ ls -l /lib/x86_64-linux-gnu/libc.so.6 lrwxrwxrwx 1 root root 12 feb 6 22:17 /lib/x86_64-linux-gnu/libc.so.6 -> libc-2.24.so
Ovaj obrazac referenciranja datoteka dijeljene biblioteke, imenovanih od strane određene verzije, općenitijim nazivima datoteka, je uobičajena praksa.
Drugi primjeri dijeljenih biblioteka uključuju libreadline
(koji omogućava korisnicima da uređuju komandne linije kako se upisuju i uključuje podršku za Emacs i vi modove uređivanja), libcrypt
(koji sadrži funkcije vezane za šifriranje, heširanje i kodiranje) , ili libcurl
(što je biblioteka za prijenos datoteka s više protokola).
Česte lokacije za dijeljene biblioteke u Linux sistemu su:
-
/lib
-
/lib32
-
/lib64
-
/usr/lib
-
/usr/local/lib
Note
|
Koncept dijeljenih biblioteka nije isključiv za Linux. U Windowsu se, na primjer, zovu DLL što je skraćenica za dinamički-povezane biblioteke. |
Konfiguracija putanje dijeljenih bibloteka
Reference sadržane u dinamički povezanim programima rješavaju se pomoću dinamičkog linkera (ld.so
ili ld-linux.so
) kada se program pokrene. Dinamički linker traži biblioteke u više direktorija. Ovi direktoriji su specificirani putem bibliotečke putanje. Putanja biblioteke je konfigurisana u direktoriju /etc
, odnosno u datoteci /etc/ld.so.conf
i, danas češće, u datotekama koje se nalaze u /etc/ld.so.conf.d
direktoriju. Obično, prvi uključuje samo jednu liniju include
za *.conf
datoteke u drugom:
$ cat /etc/ld.so.conf include /etc/ld.so.conf.d/*.conf
Direktorij /etc/ld.so.conf.d
sadrži *.conf
datoteke:
$ ls /etc/ld.so.conf.d/ libc.conf x86_64-linux-gnu.conf
Ove *.conf
datoteke moraju uključivati apsolutne putanje do direktorija dijeljene biblioteke:
$ cat /etc/ld.so.conf.d/x86_64-linux-gnu.conf # Multiarch support /lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu
Komanda ldconfig
brine se za čitanje ovih konfiguracijskih datoteka, stvarajući gore spomenuti skup simboličkih veza koje pomažu u lociranju pojedinačnih biblioteka i konačno za ažuriranje keš datoteke /etc/ld.so.cache
. Stoga, ldconfig
mora biti pokrenut svaki put kada se konfiguracijski fajlovi dodaju ili ažuriraju.
Korisne opcije za ldconfig
su:
-v
,--verbose
-
Prikažite brojeve verzija biblioteke, naziv svakog direktorija i veze koje su kreirane:
$ sudo ldconfig -v /usr/local/lib: /lib/x86_64-linux-gnu: libnss_myhostname.so.2 -> libnss_myhostname.so.2 libfuse.so.2 -> libfuse.so.2.9.7 libidn.so.11 -> libidn.so.11.6.16 libnss_mdns4.so.2 -> libnss_mdns4.so.2 libparted.so.2 -> libparted.so.2.0.1 (...)
Tako možemo vidjeti, na primjer, kako je
libfuse.so.2
povezan sa stvarnim zajedničkim objektnim fajlomlibfuse.so.2.9.7
. -p
,--print-cache
-
Ispišite liste direktorija i biblioteka kandidata pohranjenih u trenutnoj keš memoriji:
$ sudo ldconfig -p 1094 libs found in the cache `/etc/ld.so.cache' libzvbi.so.0 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libzvbi.so.0 libzvbi-chains.so.0 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libzvbi-chains.so.0 libzmq.so.5 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libzmq.so.5 libzeitgeist-2.0.so.0 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libzeitgeist-2.0.so.0 (...)
Obratite pažnju kako keš koristi potpuno kvalifikovan soname linkova:
$ sudo ldconfig -p |grep libfuse libfuse.so.2 (libc6,x86-64) => /lib/x86_64-linux-gnu/libfuse.so.2
Ako dugo listamo /lib/x86_64-linux-gnu/libfuse.so.2
, naći ćemo referencu na stvarni zajednički objektni fajl libfuse.so.2.9.7
koji je pohranjen u istom direktoriju:
$ ls -l /lib/x86_64-linux-gnu/libfuse.so.2 lrwxrwxrwx 1 root root 16 Aug 21 2018 /lib/x86_64-linux-gnu/libfuse.so.2 -> libfuse.so.2.9.7
Note
|
Budući da zahtijeva pristup pisanju u |
Pored gore opisanih konfiguracijskih datoteka, varijabla okruženja LD_LIBRARY_PATH
može se koristiti za privremeno dodavanje novih putanja za dijeljene biblioteke. Sastoji se od skupa direktorija odvojenih dvotačkama (:
) u kojima se traže biblioteke. Da biste, na primjer, dodali /usr/local/mylib
putanji biblioteke u trenutnoj sesiji šela, možete upisati:
$ LD_LIBRARY_PATH=/usr/local/mylib
Sada provjerite njenu vrijednost:
$ echo $LD_LIBRARY_PATH /usr/local/mylib
Da biste dodali /usr/local/mylib
putanji biblioteke u trenutnoj sesiji šela i da biste ga izvezli u sve podređene procese iz tog šela, unjeli biste:
$ export LD_LIBRARY_PATH=/usr/local/mylib
Za uklanjanje LD_LIBRARY_PATH
varijable okruženja, unosite:
$ unset LD_LIBRARY_PATH
Da biste izvršili trajne izmjene, unosite liniju
export LD_LIBRARY_PATH=/usr/local/mylib
u jednoj od Bash inicijalizacijskih skripti kao što je /etc/bash.bashrc
ili ~/.bashrc
.
Note
|
|
Traženje zavisnosti određenih izvršnih datoteka
Da biste potražili dijeljene biblioteke koje zahtijevaju određeni program, koristite komandu ldd
nakon koje slijedi apsolutna putanja do programa. Izlaz prikazuje putanju datoteke dijeljene biblioteke kao i heksadecimalnu memorijsku adresu na kojoj se učitava:
$ ldd /usr/bin/git linux-vdso.so.1 => (0x00007ffcbb310000) libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f18241eb000) libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f1823fd1000) libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x00007f1823db6000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f1823b99000) librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f1823991000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f18235c7000) /lib64/ld-linux-x86-64.so.2 (0x00007f182445b000)
Također, koristimo ldd
za pretragu zavisnosti dijeljenih objekata:
$ ldd /lib/x86_64-linux-gnu/libc.so.6 /lib64/ld-linux-x86-64.so.2 (0x00007fbfed578000) linux-vdso.so.1 (0x00007fffb7bf5000)
Sa -u
(ili --unused
) opcijom ldd
ispisuje neiskorištene direktne zavisnosti (ako postoje):
$ ldd -u /usr/bin/git Unused direct dependencies: /lib/x86_64-linux-gnu/libz.so.1 /lib/x86_64-linux-gnu/libpthread.so.0 /lib/x86_64-linux-gnu/librt.so.1
Razlog za neiskorištene ovisnosti povezan je s opcijama koje linker koristi prilikom izgradnje binarne datoteke. Iako programu nije potrebna neiskorištena biblioteka, ona je i dalje povezana i označena kao NEEDED
u informacijama o objektnoj datoteci. Ovo možete istražiti koristeći komande kao što su readelf
ili objdump
, koje ćete uskoro koristiti u istraživačkoj vježbi.
Vođene vježbe
-
Podijelite sljedeće nazive zajedničkih biblioteka na njihove dijelove:
Complete file name Library name so suffix Version number linux-vdso.so.1
libprocps.so.6
libdl.so.2
libc.so.6
libsystemd.so.0
ld-linux-x86-64.so.2
-
Razvili ste dio softvera i želite dodati novi direktorij dijeljene biblioteke svom sistemu (
/opt/lib/mylib
). Njegovu apsolutnu putanju upisujete u datoteku pod nazivommylib.conf
.-
U koji direktorij treba da stavite ovu datoteku?
-
Koju komandu treba pokrenuti da bi promjene bile u potpunosti efektivne?
-
-
Koju komandu biste koristili za popis dijeljenih biblioteka koje zahtijeva
kill
?
Istraživačke vježbe
objdump
je uslužni program komandne linije koji prikazuje informacije iz objektnih datoteka. Provjerite da li je instaliran u vašem sistemu pomoću which objdump
. Ako nije, instalirajte ga.+
* Koristite objdump
sa opcijom -p
(ili --private-headers
) i grep
da ispišete zavisnosti od glibc
:+
* Koristite `objdump` sa opcijom `-p` (ili `--private-headers`) i `grep` da ispišete soname od `glibc`:
+
*Koristite objdump
sa opcijom -p
(ili --private-headers
) i grep
da ispišete zavisnosti Basha:
Sažetak
U ovoj lekciji ste naučili:
-
Šta je dijeljena (ili dinamička) biblioteka.
-
Razlike između dijeljenih i statičkih biblioteka.
-
Imena zajedničkih biblioteka (sonames).
-
Preferirane lokacije za dijeljene biblioteke u Linux sistemu kao što su
/lib
ili/usr/lib
. -
Svrha dinamičkog linkera
ld.so
(ilild-linux.so
). -
Kako konfigurirati putanje dijeljene biblioteke pomoću datoteka u
/etc/
kao što jeld.so.conf
ili onih uld.so.conf.d
direktoriju. -
Kako konfigurirati putanje dijeljene biblioteke pomoću varijable okruženja
LD_LIBRARY_PATH
. -
Kako potražiti ovisnosti o izvršnoj i dijeljenoj biblioteci.
Komande korištene u ovoj lekciji:
ls
-
Prikaži sadržaj direktorija
cat
-
Konkateniraj datoteke i prikaži na standardni izlaz.
sudo
-
Izvršavanje komandi sa administrativnim privilegijama.
ldconfig
-
Konfiguracija dinamičkog linkera za vrijeme izvođenja.
echo
-
Prikaži vrijednost varijable okruženja.
export
-
Ekrsportuj vrijednost varijable okruženja u aktivni šel.
unset
-
Ukloni varijablu okruženja.
ldd
-
Prikaži ovisnosti programa dijeljenih objekata.
readelf
-
Prikaži informacije o ELF datotekama (ELF stands for executable and linkable format).
objdump
-
Prikaži informacije iz objekt datoteka.
Odgovori na vođene vježbe
-
Podijelite sljedeće nazive zajedničkih biblioteka na njihove dijelove:
Complete file name Library name so suffix Version number linux-vdso.so.1
linux-vdso
so
1
libprocps.so.6
libprocps
so
6
libdl.so.2
libdl
so
2
libc.so.6
libc
so
6
libsystemd.so.0
libsystemd
so
0
ld-linux-x86-64.so.2
ld-linux-x86-64
so
2
-
. Razvili ste dio softvera i želite dodati novi direktorij dijeljene biblioteke svom sistemu (
/opt/lib/mylib
). Njegovu apsolutnu putanju upisujete u datoteku pod nazivommylib.conf
.-
U koji direktorij treba da stavite ovu datoteku?
/etc/ld.so.conf.d
-
Koju komandu treba pokrenuti da bi promjene bile u potpunosti efektivne?
ldconfig
-
-
Koju komandu biste koristili za popis dijeljenih biblioteka koje zahtijeva
kill
?ldd /bin/kill
Odgovori na istraživačke vježbe
-
objdump
je uslužni program komandne linije koji prikazuje informacije iz objektnih datoteka. Provjerite da li je instaliran u vašem sistemu pomoćuwhich objdump
. Ako nije, instalirajte ga.-
Koristite
objdump
sa opcijom-p
(ili--private-headers
) igrep
da ispišete zavisnosti odglibc
:objdump -p /lib/x86_64-linux-gnu/libc.so.6 | grep NEEDED
-
Koristite
objdump
sa opcijom-p
(ili--private-headers
) igrep
da ispišete soname odglibc
:objdump -p /lib/x86_64-linux-gnu/libc.so.6 | grep SONAME
-
Koristite
objdump
sa opcijom-p
(ili--private-headers
) igrep
da ispišete zavisnosti Basha:objdump -p /bin/bash | grep NEEDED
-