La commande ldd (List Dynamic Dependencies) sous Bash

Documentation de la commande ldd sous Bash

📌 Introduction

La commande ldd (List Dynamic Dependencies) est un outil en ligne de commande sous Linux et autres systèmes Unix-like qui permet d’afficher les bibliothèques partagées (ou shared libraries) dépendantes d’un programme exécutable ou d’une bibliothèque dynamique. Elle est particulièrement utile pour le débogage, la vérification de compatibilité, ou l’analyse des dépendances entre logiciels.


📖 Description

ldd est un script shell ou un binaire (selon la distribution) qui :

  • Liste les bibliothèques dynamiques requises par un fichier exécutable ou une bibliothèque partagée.
  • Vérifie si toutes les dépendances sont disponibles et accessibles.
  • Affiche le chemin absolu de chaque bibliothèque chargée.
  • Signale les bibliothèques manquantes ou introuvables.

⚠️ Note : ldd ne fonctionne pas avec des fichiers statiques (compilés avec -static).


🔹 Syntaxe

ldd [OPTIONS] FICHIER...
ArgumentDescription
FICHIERChemin vers un exécutable ou une bibliothèque partagée (.so).

🎛️ Options disponibles

OptionDescription
-v ou –verboseAffiche des informations détaillées, comme la version de chaque bibliothèque.
-u ou –unusedAffiche les dépendances non utilisées (si supporté par le système).
-d ou –data-relocsEffectue des relocations de données et affiche les dépendances correspondantes.
-r ou –function-relocsEffectue des relocations de fonctions et affiche les dépendances.
–helpAffiche l’aide et quitte.
–versionAffiche la version de ldd et quitte.

ℹ️ Certaines options peuvent varier selon la version de glibc ou du système d’exploitation.


📂 Exemples d’utilisation

1️⃣ Lister les dépendances d’un exécutable

ldd /bin/ls

Sortie typique :

linux-vdso.so.1 (0x00007ffd12345000)
libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f1234567000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1234345000)
libpcre2-8.so.0 => /lib/x86_64-linux-gnu/libpcre2-8.so.0 (0x00007f1234123000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f1234012000)
/lib64/ld-linux-x86-64.so.2 (0x00007f12345e7000)

2️⃣ Vérifier les dépendances d’un programme personnalisé

# Compilation d'un programme C simple
cc mon_programme.c -o mon_programme

# Affichage des dépendances
ldd ./mon_programme

3️⃣ Mode verbeux (avec versions)

ldd -v /usr/bin/python3

4️⃣ Vérifier les dépendances d’une bibliothèque partagée

ldd /usr/lib/x86_64-linux-gnu/libz.so.1

5️⃣ Détecter des bibliothèques manquantes

Si une bibliothèque est manquante, ldd affichera un message comme :

libmissing.so => not found

🔍 Comprendre la sortie de ldd

La sortie de ldd suit généralement ce format :

NOM_BIBLIOTHEQUE => CHEMIN_VERS_BIBLIOTHEQUE (ADRESSE_MEMOIRE)
ColonneDescription
NOM_BIBLIOTHEQUENom de la bibliothèque partagée (ex: libc.so.6).
=> CHEMIN_VERS_BIBLIOTHEQUEChemin absolu où la bibliothèque est trouvée.
(ADRESSE_MEMOIRE)Adresse mémoire où la bibliothèque est chargée (optionnelle).

Cas particuliers

  • not found : La bibliothèque est manquante ou introuvable dans les chemins de recherche (LD_LIBRARY_PATH, /etc/ld.so.cache, etc.).
  • (0xXXXXXXXX) : La bibliothèque est chargée en mémoire, mais son chemin n’est pas affiché (ex: linux-vdso.so.1).

⚙️ Fonctionnement interne

ldd fonctionne en :

  1. Analysant les en-têtes ELF du fichier pour trouver la section .dynamic (qui contient les dépendances).
  2. Résolvant les noms des bibliothèques via le dynamic linker (ld-linux.so ou ld.so).
  3. Affichant les chemins résolus ou les erreurs de résolution.

🔗 Note technique : ldd utilise le dynamic linker (ld.so) pour résoudre les dépendances. Sur la plupart des systèmes, ldd est un script qui appelle ld.so avec des options spécifiques.


🛠️ Variables d’environnement utiles

VariableDescription
LD_LIBRARY_PATHListe de chemins supplémentaires où chercher les bibliothèques partagées (séparés par :).
LD_PRELOADListe de bibliothèques à charger avant toute autre dépendance.
LD_DEBUGActive le débogage du dynamic linker (ex: LD_DEBUG=libs ldd /bin/ls).

Exemple avec LD_LIBRARY_PATH :

# Chercher d'abord dans /mon/chemin/perso
LD_LIBRARY_PATH=/mon/chemin/perso ldd ./mon_programme

⚠️ Avertissements et bonnes pratiques

❌ À éviter

  • Ne pas utiliser ldd sur des fichiers non fiables : Exécuter ldd sur un fichier malveillant peut entraîner l’exécution de code arbitraire (car ldd charge les bibliothèques).
  • Éviter ldd sur des binaires corrompus : Cela peut causer des erreurs de segmentation.

✅ Bonnes pratiques

  • Utiliser ldd pour le débogage : Idéal pour vérifier les dépendances manquantes après une compilation.
  • Vérifier les chemins avec ldconfig : Utilisez ldconfig -p pour lister les bibliothèques connues du système.
  • Préférer objdump ou readelf pour une analyse statique :objdump -p mon_programme | grep NEEDED readelf -d mon_programme | grep NEEDED

🔄 Alternatives à ldd

OutilDescription
objdump -pAffiche les en-têtes ELF, y compris les dépendances (NEEDED).
readelf -dAffiche la section .dynamic d’un fichier ELF.
otool -L (macOS)Équivalent de ldd sur macOS.
dumpbin /DEPENDENTS (Windows)Affiche les dépendances d’un exécutable sous Windows.

📚 Exemple complet : Résolution d’un problème de dépendance

Problème

Un programme mon_app ne s’exécute pas avec l’erreur :

./mon_app: error while loading shared libraries: libcustom.so: cannot open shared object file: No such file or directory

Étapes de résolution

  1. Vérifier les dépendances : ldd ./mon_app → Affiche libcustom.so => not found.
  2. Localiser la bibliothèque : find / -name "libcustom.so*" 2>/dev/null → Trouve /usr/local/lib/libcustom.so.
  3. Ajouter le chemin temporairement : LD_LIBRARY_PATH=/usr/local/lib ldd ./mon_app → Vérifie que la dépendance est résolue.
  4. Solution permanente :
    • Ajouter /usr/local/lib à /etc/ld.so.conf puis exécuter ldconfig.
    • Ou utiliser LD_LIBRARY_PATH dans le script de lancement.

📊 Tableau récapitulatif des codes de sortie

Code de sortieSignification
0Toutes les dépendances sont résolues.
1Au moins une dépendance est manquante.
2Erreur d’utilisation (ex: fichier introuvable).

📖 Ressources supplémentaires


💡 Astuces avancées

1. Lister les dépendances récursives

Pour lister toutes les dépendances (y compris celles des bibliothèques dépendantes), utilisez :

ldd -r /chemin/vers/executable

2. Vérifier les dépendances d’un processus en cours d’exécution

# Trouver le PID du processus
pidof mon_programme

# Lister les bibliothèques chargées (nécessite root)
cat /proc/<PID>/maps | grep \.so

3. Utiliser strace pour déboguer le chargement des bibliothèques

strace -e openat ldd /chemin/vers/executable 2>&1 | grep \.so

🧪 Exercice pratique

  1. Compilez ce programme C (test.c) : #include <stdio.h> int main() { printf("Hello, ldd!\n"); return 0; }
  2. Exécutez ldd sur le résultat : ldd ./test
  3. Observez les dépendances (ex: libc.so.6).
  4. Essayez de supprimer une dépendance (simulée) : LD_LIBRARY_PATH=/chemin/inexistant ldd ./test

📝 Résumé

CommandeUtilité
ldd /chemin/vers/fichierLister les dépendances d’un exécutable.
ldd -v /chemin/vers/fichierAfficher les versions des bibliothèques.
LD_LIBRARY_PATH=/chemin ldd fichierTester avec un chemin personnalisé.
ldconfig -pLister les bibliothèques connues du système.

ldd est un outil indispensable pour comprendre et résoudre les problèmes de dépendances sous Linux. Utilisez-le avec prudence et combinez-le avec d’autres outils (ldconfig, strace, objdump) pour un débogage efficace.


Voir également

Localiser l’emplacement du fichier exécutable d’une commande avec which

Retour en haut