Un programme ne fonctionne pas ? Il plante sans raison apparente ? strace et ltrace sont tes meilleurs alliés pour comprendre ce qu'un programme fait vraiment — en regardant les appels système et les appels aux bibliothèques partagées.
strace intercepte et enregistre les appels système (syscalls) qu'un programme effectue vers le noyau Linux. Chaque fois qu'un programme ouvre un fichier, lit du réseau, alloue de la mémoire ou crée un processus, c'est un appel système. En gros : strace te montre la conversation entre le programme et le noyau. sudo apt install strace
strace -V
strace ls -l /tmp
strace ./mon_script.sh Tu verras une longue liste d'appels comme : brk(NULL) = 0x55a3c000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT open("/etc/ld.so.cache", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=...) = 0 mmap(NULL, ..., PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f... open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY) = 3
Chaque ligne strace suit ce format :
^nom de l'appel ^ses arguments ^valeur de retour (fd=3)
- Valeur de retour positive : l'appel a réussi (ex : descripteur de fichier 3)
- Valeur = -1 : l'appel a échoué, suivi du code d'erreur (ex : ENOENT = fichier non trouvé, EACCES = permission refusée)
strace -e openat ls /tmp
strace -e trace=open,read,write cat /etc/hostname
strace -c ls /tmp
strace -e trace=open -P /root ls /tmp
strace -o /tmp/trace.txt ls /tmp
less /tmp/trace.txt
ps aux | grep firefox
sudo strace -p 1234
sudo strace -fp 1234
strace -t ls /tmp
strace -tt ls /tmp
strace -r ls /tmp
ltrace intercepte les appels aux bibliothèques partagées (librairies .so). Là où strace montre les appels au noyau, ltrace montre les appels aux fonctions des bibliothèques (libc, pthread, etc.). sudo apt install ltrace
ltrace ls /tmp Exemple de sortie : malloc(32) = 0x55a... strcmp("HOME", "HOME") = 0 getenv("HOME") = "/home/david" strlen("/home/david") = 10 strcpy(0x55..., "/home/david") = 0x55...
ltrace -c ls /tmp
ltrace -e malloc,free ls /tmp
sudo ltrace -p 1234
ltrace -i ls /tmp
strace -e openat ./mon_programme 2>&1 | grep ENOENT
strace -e openat ./mon_programme 2>&1 | grep -i "Aucun fichier" Tu verras exactement quel fichier le programme essaie d'ouvrir.
strace -e trace=open,execve ./programme_fantome 2>&1 | grep -E "ENOENT|EACCES|ERR"
strace -e signal=none -e trace=none -f ./programme_fantome
strace -c -e trace=open,read,write,execve ./programme_lent
strace -e openat ./programme_lent 2>&1 | head -30
strace -e trace=connect,socket,bind ./mon_service
strace -e trace=network ./script_reseau
strace -f -o /tmp/script_trace.log ./script.sh
grep -E "ENOENT|EACCES" /tmp/script_trace.log
| Outil | Ce qu'il trace | Cas d'usage |
|---|---|---|
ltrace |
Appels aux bibliothèques partagées | Fonctions malloc/free, printf, libc |
strace -c |
Résumé statistique | Trouver les goulots d'étranglement |
strace -p |
Processus existant (PID) | Déboguer un programme déjà lancé |
| ## 7. Combiner strace et ltrace | ||
| (strace -f -e trace=execve ./programme 2>&1) | grep ENOENT | |
| (ltrace -f ./programme 2>&1) | grep NULL | |
| # Enregistrer les deux dans des fichiers séparés | ||
| strace -o /tmp/strace.log ./programme & | ||
| ltrace -o /tmp/ltrace.log ./programme | ||
> Warning : ⚠️ Performance : strace ralentit considérablement le programme tracé (surtout avec -f). Utilise-le sur des programmes qui ne sont pas en production critique, ou en lecture seule. |
||
| ## Exercice pratique | ||
| Objectif : Utilise strace et ltrace pour comprendre le comportement d'un programme simple. | ||
- Installe les outils : sudo apt install strace ltrace |
||
- strace -e openat ls /var/log 2>&1 | head -20 |
||
- Observe les fichiers ouverts par ls |
||
- Utilise le mode résumé : strace -c ls /tmp |
||
- Trace avec ltrace : ltrace -c ls /tmp 2>&1 | head -20 |
||
| cat /etc/hostname | ||
| mkdir /tmp/test_debug | ||
| echo "OK" > /tmp/test_debug/fichier.txt | ||
- Trace-le avec strace : strace -f -o /tmp/script_trace.log ./test.sh |
||
- Cherche les erreurs : grep -E "ENOENT|EACCES" /tmp/script_trace.log |
||
- Utilise ltrace sur le script : ltrace -f ./test.sh 2>&1 | grep getenv |
||
| ## Résumé | ||
| Commande | Rôle | |
| --- | --- | |
strace -e openat <commande> |
Ne tracer qu'un appel précis | |
strace -c <commande> |
Résumé statistique des appels | |
strace -p <PID> |
Attacher à un processus existant | |
strace -o fichier.log <commande> |
Sauvegarder la trace dans un fichier | |
ltrace <commande> |
Tracer les appels aux bibliothèques | |
ltrace -c <commande> |
Résumé statistique des appels bibliothèques | |
strace -f <commande> |
Suivre aussi les processus enfants (fork) | |
| strace et ltrace sont des outils puissants pour comprendre ce qui se passe vraiment dans un programme. En cas de doute, trace tout et cherche les erreurs — elles ne mentent jamais. |