Les HOWTO Linux...
Page suivante - Page précédente - Table des matières
7. Chargement dynamique
Ce paragraphe est en fait un peu court : il sera étendu dans une version ultérieure dès que j'aurai récupéré le HowTo ELF
7.1 Concepts
Linux possède des bibliothèques dynamiques, comme on vous le répète depuis le début de ce document ! Or, il existe un système pour reporter le travail d'association des noms des symboles et de leur adresse dans la bibliothèque, qui est normalement effectué lors de l'édition de liens en l'effectuant lors du chargement du programme.
7.2 Messages d'erreur
Envoyez moi vos erreurs ! Je n'en fait pas grand chose sauf les insérer dans ce paragraphe...
-
can't load library: /lib/libxxx.so, Incompatible version
(seulement a.out) Cela signifie que vous n'avez pas la version correcte de la bibliothèque (numéro dit majeur). Non, il n'est pas possible d'effectuer un lien symbolique sur la bibliothèque que vous possédez : si vous avez de la chance, vous obtiendrez un segmentation fault. Récupérez la nouvelle version. Un message un peu équivalent existe également sur les systèmes ELF :
ftp: can't load library 'libreadline.so.2'
warning using incompatible library version xxx
(seulement a.out) Vous avez un numéro de version de bibliothèque (mineur) inférieur à la version avec laquelle a été compilé le programme. Le programme fonctionnera sûrement. Une mise à jour est toutefois conseillée.
7.3 Contrôler l'opération de chargement dynamique
Il existe certaines variables d'environnements que le chargeur dynamique
utilise. Beaucoup sont exploitées par le programme ldd
lorsqu'il
s'agit de particularités de l'environnement de l'utilisateur, ce qui
peuvent être positionnées pour lancer ldd avec des options
particulières. Voici une description des différentes variables d'environnement
que vous pouvez rencontrer :
-
LD_BIND_NOW
--- normalement, les fonctions ne sont pas cherchées dans les bibliothèques avant leur appel. En positionnant cette option, vous vérifiez que toutes les fonctions employées dans votre programmes se trouvent bien dans la bibliothèque lors de son chargement, ce qui ralentit le lancement du programme. C'est utile lorsque vous voulez tester que l'édition de liens s'est parfaitement déroulée et que tous les symboles sont bien associés. -
LD_PRELOAD
peut être défini avec un nom de fichier qui contient des fonctions surchargeant des fonctions déjà existantes. Par exemple, si vous testez une stratégie d'allocation mémoire, et que vous voulez remplacer le malloc de la bibliothèque C par le vôtre situé dans un module ayant pour nommalloc.o
, il vous suffit de faire :$ export LD_PRELOAD=malloc.o $ test_mon_malloc
LD_ELF_PRELOAD
etLD_AOUT_PRELOAD
sont similaires, mais leur utilisation est spécifique au type de binaire utilisé. SiLD_
TypeBinaire_PRELOAD
etLD_PRELOAD
sont positionnés, celui correspondant le mieux à la machine est utilisé. -
LD_LIBRARY_PATH
contient une liste de répertoires contenant les bibliothèques dynamiques. Cela n'affecte pas l'édition de liens : cela n'a qu'un effet lors de l'exécution. Il faut noter qu'elle est désactivée pour des programmes qui s'exécutent avec un setuid ou un setgid. Enfin,LD_ELF_LIBRARY_PATH
etLD_AOUT_LIBRARY_PATH
peuvent être utilisés pour orienter le mode de compilation du binaire.LD_LIBRARY_PATH
ne devrait pas être nécessaire en principe : ajoutez les répertoires dans le fichier/etc/ld.so.conf/
et relancez ldconfig. -
LD_NOWARN
s'applique au format a.out uniquement. Lorsqu'elle est positionnée (c.a.d si elle existe par exemple avecLD_NOWARN=true; export LD_NOWARN
) cela arrête le chargeur du programme même sur des avertissements insignifiants (tels que des messages d'incompatibilités de numéros mineurs de version). -
LD_WARN
s'applique à ELF uniquement. Lorsqu'elle est positionnée, on transforme le message habituellement fatal Can't find library en un avertissement. Ce n'est pas positionné par défaut mais c'est important pour un programme comme ldd. -
LD_TRACE_LOADED_OBJECTS
s'applique à ELF uniquement, et permet de simuler l'exécution des programmes comme s'ils l'étaient parldd
:$ LD_TRACE_LOADED_OBJECTS=true /usr/bin/lynx libncurses.so.1 => /usr/lib/libncurses.so.1.9.6 libc.so.5 => /lib/libc.so.5.2.18
7.4 Ecrire des programmes en utilisant le chargement dynamique
Cela ressemble énormément au système de chargement dynamique
utilisé sous Solaris 2.x. Ce système est décrit d'une
manière précise dans le document expliquant la programmation
avec ELF écrit par H J Lu et dans la page de manuel
dlopen(3)
, qui se trouve dans le paquetage ld.so.
Voici un exemple simple : pensez à faire l'édition de liens avec
-ldl
#include <dlfcn.h>
#include <stdio.h>
main()
{
void *libc;
void (*printf_call)();
if(libc=dlopen("/lib/libc.so.5",RTLD_LAZY))
{
printf_call = dlsym(libc,"printf");
(*printf_call)("Bonjour ! Ha ben ca marche pil poil sous Linux !\n");
}
}
Page suivante - Page précédente - Table des matières