IMPORTANT: Per accedir als fitxer de subversion: http://acacha.org/svn (sense password). Poc a poc s'aniran migrant els enllaços. Encara però funciona el subversion de la farga però no se sap fins quan... (usuari: prova i la paraula de pas 123456)

Linux Professional Institute Certificate. LPIC-1

Lpic1 large.gif
Certificat LPIC-1
Examen: 101 (torneu a la resta de temes)
Fitxers: LPI102.3_Gestionar_biblioteques_compartides.pdf (LPI102.3_Gestionar_biblioteques_compartides.odp),
Objectius: http://www.lpi.org/eng/certification/the_lpic_program/lpic_1/exam_101_detailed_objectives
Dipòsit SVN: https://svn.projectes.lafarga.cat/svn/lpi/Materials/Examen_101/102.3
Usuari: anonymous
Paraula de pas: qualsevol paraula de pas

Objectius del tema

102.3. Gestionar biblioteques compartides
Objective.jpg
  • Objectiu: Els candidats han de ser capaços de determinar les llibreries compartides de les que depenen el programari executable i instal·lar-les quan sigui necessari.
  • Pes: 1
060317 Icon - Theory of Knowledge v01 pdc.jpg

Àrees Clau de Coneixement:

  • Identificar les llibreries compartides.
  • Identificar les ubicacions típiques per a les llibreries del sistema.
  • Carregar llibreries compartides.
Icon list.jpg

La següent és una llista parcial de fitxers, termes i utilitats utilitzades:

Text-editor.svg

Apunts: LPI 102.3. Gestionar biblioteques compartides

Biblioteques compartides (shared libraries)

NOTA: Tingueu en compte que library és un típic false friend que sovint es tradueix per llibreria. Realment la traducció és biblioteca. De totes maneres és un error tant comú que gairebé es considera correcte. Recull de termes de softcatalà

La majoria d'aplicacions Linux tenen fortes dependències amb el que s'anomenen biblioteques compartides o en anglès, shared libraries. Aquestes biblioteques també són conegudes com a biblioteques dinàmiques.

Al instal·lar una aplicació que depèn de biblioteques compartides, cal tenir instal·lada la biblioteca compartida i, sovint, a més la versió de la biblioteca adequada.

L'objectiu de les biblioteques es facilitar la tasca dels programadors proveint mòduls, funcions o fragments de codi reutilitzables. Per exemple, una de les biblioteques més importants és libc, la biblioteca de C, però també hi ha altres biblioteques com totes les associades a entorns gràfics d'usuari (GUI) que proporcionen a les aplicacions el suport per a treballar amb finestres i ginys (widgets) gràfics com desplegables, caixes de selecció, etc.

NOTA: Linux utilitza la biblioteca GNU C libray (glibc)

Les dos biblioteques gràfiques més utilitzades són GIMP Tool Kit (GTK+) i Qt.

Cal tenir en compte que les biblioteques són seleccionades pels programadors de les aplicacions i no pas pels usuaris i per tant els usuaris no podem escollir en quina biblioteca volem treballar.

Les rutines proporcionades per una biblioteca compartida, en principi poden ser utilitzades en una aplicació com qualsevol altre biblioteca, però això té certs problemes:

  • Si cada aplicació conté una còpia de la biblioteca compartida, estem malgastant espai i la mida de les aplicacions augmenta considerablement
  • Cal tenir en compte que no només augmenta la mida que ocupa l'aplicació, sinó també l'ús de RAM. Si varies aplicacions executen diversos cops el mateix tros de codi estem malgastant la RAM.
  • El programes no poden obtenir els avantatges d'una actualització de la biblioteca compartida sense recompilar (o relinking).

Per aquesta raó, la majoria de programes utilitzen biblioteques compartides, de forma que l'aplicació no inclou la majoria de funcions rutinàries, sinó que són les biblioteques compartides les que realitzen aquestes tasques, de forma que s'optimitza l'ús del recursos del sistema.

NOTA: El concepte de biblioteca compartida és similar al concepte de DLL a Windows

Les biblioteques compartides utilitzen les següents extensions:

.so 

o

.so.version

Els inconvenients de les biblioteques compartides són:

  • El primer programa en utilitzar la biblioteca compartida és una mica més temps ja que ha de carregar aquesta biblioteca.
  • Poden provocar complicacions en la gestió del programari (instal·lacions, actualitzacions, etc...)

Quan hi ha un canvi en una biblioteca compartida, aquest canvi pot provocar que algunes aplicacions que l'utilitzen deixin de funcionar per incompatibilitats. Linux per tal d'evitar aquest tipus de problemes utilitza un esquema de numeració que permet als usuaris mantenir instal·lades al mateix temps múltiples versions d'una mateixa biblioteca compartida.

Quan hi ha una actualització de la biblioteca que es sap que no té incompatibilitats, es modifica la biblioteca instal·lada al sistema, però quan es tracta d'una actualització major, amb canvis en el funcionament de la biblioteca, aleshores s'instal·la la nova versió mantenint també l'antiga versió,

Això minimitza els problemes però encara i així, de tant en tant us podeu trobar errors amb biblioteques compartides.

Procés de compilació

CompilacioMuntatge3.png

Consulteu:

Procés d'enllaçament de biblioteques

Les bilioteques poden ser de dos tipus:

  • Estàtiques: És un arxiu, amb un conjunt de rutines que es copien a una aplicació durant procés de compilació a través del enllaçador (ld), també conegut com a muntador. Cada biblioteca produeix un fitxer .o que es pot executar de forma independent. Al procés de compilació se'l coneix com a construcció estàtica de l'aplicació objectiu. L'adreça real, les referències per a salts i altres crides a rutines s'emmagatzemen en una adreça relativa o simbòlica, que no pot resoldre's fins que tot el codi i les biblioteques són assignades a adreces estàtiques finals.
  • Dinàmiques o compartides: Enllaç dinàmic significa que les rutines d'una biblioteca són carregades en un programa en temps d'execució, en lloc ser enllaçades en temps de compilació. Es mantenen com arxius independents separats del fitxer executable del programa principal. En aquests casos l'enllaçador realitza una mínima quantitat de treball en temps de compilació. La major part de la labor d'enllaçat es realitza en el moment en què l'aplicació es carrega (temps de càrrega o loadtime) o durant l'execució (temps d'execució o runtime).

Localització de les biblioteques compartides

Les aplicacions han de ser capaces de localitzar les biblioteques compartides de les que depenen. Aquesta tasca es realitza modificant fitxers de configuració i variables d'entorn.

Els programes tenen dos opcions a l'hora de referir-se a una biblioteca compartida:

  • Utilitzar el nom de la biblioteca (p. ex. libc.so.6)
  • Utilitzar el camí (path) complet (p. ex. /lib/libc.so.6)

El programa encarregat de carregar les biblioteques dinàmiques en temps d'execució és ld.so. Si consulteu el manual us dirà que es segueix el següent procediment per a localitzar una biblioteca dinàmica:

  1. Utilitzar les variables d'entorn LD_LIBRARY_PATH o LD_AOUT_LIBRARY_PATH (està última només per a fitxers a.out). Si l'executable és un executable setuid/setgid aleshores aquesta variable s'ignora.
  2. Es busca la biblioteca a la cache. La cache es troba a: /etc/ld.so.cache
  3. Finalment es busca a les carpetes /lib i /usr/lib (que són les carpetes on s'han de trobar les biblioteques segons FHS)

Exemple de biblioteca compartida

$ dpkg -L e2fslibs
/.
/lib
/lib/libext2fs.so.2.4
/lib/libe2p.so.2.3
/usr
/usr/share
/usr/share/doc
/usr/share/doc/e2fslibs
/usr/share/doc/e2fslibs/copyright
/usr/share/doc/e2fslibs/changelog.Debian.gz

Biblioteques compartides a Synaptic

Si executeu synaptic:

$ gksu synaptic

Veureu que hi ha una secció dedicada a les biblioteques amb el nom biblioteques.

Com s'utilitzen les biblioteques compartides en C

Consulteu un exemple a:

El_procés_de_compilació_en_C#Llibreries_din.C3.A0miques_.28shared_object_.so_files.29

Canviar temporalment el PATH

Es pot fer esblint la variable d'entorn LD_LIBRARY_PATH. Per exemple:

$ export LD_LIBRARY_PATH=/usr/local/testlib:/opt/newlib

Si el canvi es vulgues fer de forma permanent, aleshores s'indicaria al fitxer /etc/ld.so.conf.

Corregint problemes amb les biblioteques dinàmiques

A vegades al executar un programa, podeu veure un error similar a:

$ gimp
gimp: error while loading shared libraries: libXinerama.so.1: cannot➦
  open shared object file: No such file or directory

Aquest error indica que el sistema no ha pogut trobar la bilioteca:

libXinerama.so.1

Normalment el problema és que la biblioteca no està instal·lada o que la versió no és correcte.

hard coded:

ldd

Si la biblioteca esta instal·lada podeu cercar el fitxer amb:

dpkg -L nom_paquet_de_la_biblioteca

O utilitzar eines com find o locate per tal de localitzar el fitxer.

També podem obtenir més detalls amb:

$ whereis gimp
gimp: /usr/bin/gimp ...
$ ldd  /usr/bin/gimp

Un cop localitzat el fitxer, es pot solucionar amb un enllaç simbòlic:

$ sudo ln -s biglib.so.5.2 biglib.so.5

Formats. ELF vs a.out

Consulteu:

Amb l'ordre file, podeu saber el tipus de fitxer.

Les biblioteques i l'estàndard FHS

Segons l'estàndard FHS les biblioteques les trobareu a:

  • /lib: biblioteques principals dels executables principals (carpetes /bin i /sbin).
  • /usr/lib: biblioteques secundaries de la resta d'aplicacions.

ld.so

Segons el manual:

$ man ld.so

Es tracta del enllaçador dinàmic. Si us fixeu es tracta d'una entrada de la secció 8 del manual de Linux. Si consulteu:

$ man man

La secció 8 són rutines del nucli. El nuci del sistema operatiu, es per tant qui realitza aquesta tasca.

Si busqueu "l'ordre":

$ whereis ld.so
ld: /usr/bin/ld /usr/share/man/man1/ld.1.gz

Us indica el enllaçador en temps de compilació ld

Cal tenir en compte que totes les aplicacions Linux, fins i tot el més simple hola mon en C, requereix de biblioteques dinàmiques:

$ sudo vi holamon.c:

Afegiu:

#include <stdio.h>
int main (void) {
 printf ("Hello, world!\n");
 return 0;
}

i el compileu amb:

$ gcc -Wall holamon.c -o hola

Si ara comproveu les dependències de biblioteques dinàmiques:

$ ldd hola
	linux-gate.so.1 =>  (0x00e53000)
	libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x009ff000)
	/lib/ld-linux.so.2 (0x00617000)

Per tant totes les aplicacions són incompletes i no es fins al moment de la seva execució que es vinculen amb les biblioteques compartides bàsiques per tal de funcionar correctament.

Consulteu l'apartat:

LPI_102.3._Gestionar_biblioteques_compartides#Localitzaci.C3.B3_de_les_biblioteques_compartides

Per tal de saber com es localitzen les biblioteques compartides.

Consulteu també l'ordre ld.

/lib/ld.so

Realment el fitxer té un codi de versió:

$ /lib/ld-2.10.1.so 
Usage: ld.so [OPTION]... EXECUTABLE-FILE [ARGS-FOR-PROGRAM...]
You have invoked `ld.so', the helper program for shared library executables.
This program usually lives in the file `/lib/ld.so', and special directives
in executable files using ELF shared libraries tell the system's program
loader to load the helper program from this file.  This helper program loads
the shared libraries needed by the program executable, prepares the program
to run, and runs it.  You may invoke this helper program directly from the
command line to load and run an ELF executable file; this is like executing
that file itself, but always uses this helper program from the file you
specified, instead of the helper program file specified in the executable
file you run.  This is mostly of use for maintainers to test new versions
of this helper program; chances are you did not intend to run this program.

  --list                list all dependencies and how they are resolved
  --verify              verify that given object really is a dynamically linked
                        object we can handle
  --library-path PATH   use given PATH instead of content of the environment
                        variable LD_LIBRARY_PATH
  --inhibit-rpath LIST  ignore RUNPATH and RPATH information in object names
                        in LIST
  --audit LIST          use objects named in LIST as auditors

Aquest enllaçador és per a fitxers de tipus a.out. Un exemple, amb el típic hola mon:

$ /lib/ld-2.10.1.so ./hola
Hello, world!

/lib/ld-linux.so.*

Realment el fitxer té un codi de versió:

$ /lib/ld-linux.so.2 ./hola
Hello, world!


ELF dynamic linker/loader

Ordres

ldd

Segons el manual:

$ man ldd

Mostra les dependències de biblioteques compartides d'un fitxer. La sintaxi és:

$ sudo ldd --help
Usage: ldd [OPTION]... FILE...

Vegem un exemple:

$ whereis fdisk
fdisk: /sbin/fdisk /usr/share/man/man8/fdisk.8.gz
$ ldd /sbin/fdisk 

linux-gate.so.1 => (0x00e10000) libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00110000) /lib/ld-linux.so.2 (0x0096c000)

o

$ ldd /sbin/mkfs.ext2
	linux-gate.so.1 =>  (0x00d32000) 
	libext2fs.so.2 => /lib/libext2fs.so.2 (0x00110000)
	libcom_err.so.2 => /lib/libcom_err.so.2 (0x00e5b000)
	libblkid.so.1 => /lib/libblkid.so.1 (0x0056b000)
	libuuid.so.1 => /lib/libuuid.so.1 (0x00469000)
	libe2p.so.2 => /lib/libe2p.so.2 (0x00eb7000)
	libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00646000)
	libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0x0017d000)
	/lib/ld-linux.so.2 (0x003e0000)

Les opcions són:

  • --version: Mostra el número de versió de ldd
  • -v --verbose: Mostra tota la informació
  • -d --data-relocs: recol·loca fitxers i reporta objectes perduts (només ELF)
  • -r --function-relocs: recol·loca fitxers tant per a objectes de dades com funcions, i reporta objectes perduts
  • -u --unused: Mostra dependències directes que no s'estan utilitzant.

Per consultar la versió:

$ ldd --version
ldd (EGLIBC) 2.10.1
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.

ldconfig

Segons el manual:

$ man ldconfig
...
configure dynamic linker run-time bindings

El que fa és configurar els enllaços simbòlics correctes per a les biblioteques compartides i torna a crear la cache. Les tasques que realitza són crear, actualitzar i/o eliminar els enllaços simbòlics necessaris per al correcte funcionament del enllaçador en temps d'execució (ld.so).

Els enllaçadors dinàmics de Linux (ld.so i ld-linux.so) no llegeixen el fitxer /etc/ld.so.conf cada cop que un programa s'executa. El sistema utilitza una cache que es troba al fitxer:

/etc/ld.so.cache

Es tracta d'una llista (en forma binari) que es molt més eficient que utilitzar una llista de text. El problema però es que si feu cap modificació en els camins de les biblioteques compartides aquesta cache s'ha de tornar a generar. Aquesta tasca la fa l'ordre ldconfig.

Les biblioteques es busquen a:

  • A les carpetes especificades mitjançant opcions de l'ordre ldconfig
  • Als fitxers especificats a /etc/ld.so.conf
  • A les carpetes /usr/lib i /lib

S'ha d'executar com a superusuari:

$ sudo ldconfig

Observareu que si tot va bé no us mostra cap resultat, seguint la màxima en mon Unix:

no news good news

Podeu utilitzar l'opció versió

$ sudo ldconfig -v | more
/sbin/ldconfig.real: Can't stat /lib/i486-linux-gnu: No such file or directory
/sbin/ldconfig.real: Can't stat /lib64: No such file or directory
/usr/lib/i486-linux-gnu:
	liblouis.so.0 -> liblouis.so.0.2.5
/usr/lib/alsa-lib:
  	libasound_module_conf_pulse.so -> libasound_module_conf_pulse.so
	libasound_module_ctl_pulse.so -> libasound_module_ctl_pulse.so 
	libasound_module_pcm_oss.so -> libasound_module_pcm_oss.so 
	libasound_module_pcm_pulse.so -> libasound_module_pcm_pulse.so
	libasound_module_pcm_usb_stream.so -> libasound_module_pcm_usb_stream.so
	libasound_module_pcm_vdownmix.so -> libasound_module_pcm_vdownmix.so
	libasound_module_pcm_upmix.so -> libasound_module_pcm_upmix.so
	libasound_module_pcm_bluetooth.so -> libasound_module_pcm_bluetooth.so
	libasound_module_rate_samplerate.so -> libasound_module_rate_samplerate_order.so
...

Lo normal és que tot funcioni correctament i de fet no és necessari executar implícitament aquesta ordre. Només quan afegim una nova biblioteca compartida de forma manual, cal executar:

$ sudo sbin/ldconfig -n /lib

NOTA: tingueu en compte que si instal·leu la llibreria compartida mitjançant un paquet o un gestor de paquets, el propi paquet s'encarregarà de realitzar totes les tasques necessàries

Per defecte ldconfig s'aplica al directori root. Es pot modificar aquest comportament amb l'opció -r.

Ordre file

L'ordre file es capaç de distinguir quan una biblioteca és compartida:

$ file /lib/libext2fs.so.2.4
/lib/libext2fs.so.2.4: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped

Fitxers de configuració

/etc/ld.so.conf

És el fitxer principal de configuració i estableix el PATH o camí on el enllaçador dinàmic ld.so, pot trobar les biblioteques compartides. Per exemple, en el cas d'una Ubuntu 9.10:

$ cat /etc/ld.so.conf
include /etc/ld.so.conf.d/*.conf

Els fitxers que contenen realments els path són:

$ ls /etc/ld.so.conf.d/*.conf
/etc/ld.so.conf.d/i486-linux-gnu.conf  /etc/ld.so.conf.d/libasound2.conf  /etc/ld.so.conf.d/libc.conf

Cada fitxer conté una llista de carpetes on trobar biblioteques compartides:

$ cat /etc/ld.so.conf.d/i486-linux-gnu.conf
# Multiarch support
/lib/i486-linux-gnu
/usr/lib/i486-linux-gnu
$ cat /etc/ld.so.conf.d/libasound2.conf
/usr/lib/alsa-lib

$ cat /etc/ld.so.conf.d/libc.conf
# libc default configuration
/usr/local/lib

NOTA: Les carpetes /lib i /usr/lib sempre s'utilitzen com a carpetes del path independentment de si estan a o no especificades en aquest fitxer. Consulteu Localització de les llibreries compartides.

Altres fitxers

/etc/ld.so.preload

File containing a whitespace separated list of ELF shared libraries to be loaded before the program. libraries and an ordered list of candidate

                          libraries.

/etc/ld.so.nohwcap

 When this file is present the dynamic linker will load  the  non-optimized
                          version of a library, even if the CPU supports the optimized version.

Variables d'entorn

LD_LIBRARY_PATH

Permet indicar el path o camí on cercar biblioteques compartides

Consulteu:

LD AOUT LIBRARY PATH

Consulteu:

Vegeu també

Enllaços externs