ldd /bin/bashlistera les bibliothèques dont bash dépend.
Quel est l'intérêt de pouvoir instrumenter les opérations du chargeur dynamique me direz-vous ? Cela permet - entre autres - de tracer l'appel et le retour de fonctions appartenant aux bibliothèques partagées. La signature des fonctions permet de détailler le nombre et le type des arguments ainsi que le type de la valeur de retour. Les amateurs de ltrace apprécieront la similitude.
La différence entre les deux outils provient du fait que latrace utilise une interface inexploitée du chargeur dynamique nommée rtld-audit, disponible sur les libc dont la version est supérieure ou égale à 2.4. Cette dernière est inspirée par l'interface d'audit de Solaris. Là où ltrace échoue à tracer des applications multithreadées, latrace s'en sort haut la main.
La dernière version de latrace, la 0.5.9, date de mai 2010. Latrace est sous licence GPLv3. Si vous vous retrouvez un jour bloqué par ltrace, pensez à latrace !
Aller plus loin
- Site de latrace (32 clics)
- Page de manuel de rtld-audit (3 clics)
- Code source de latrace-0.5.9 (7 clics)
- Page de manuel de latrace (8 clics)
- Ltrace vu de l'intérieur (9 clics)
- Ltrace ne permet pas de tracer des applications multithreadées (5 clics)
# Instrumenter ?
Posté par rpnpif . Évalué à 1.
Que signifie instrumenter un chargeur dynamique ? Bin oui, quel est l'intérêt d'instrumenter ?
Pourrait-on décomplexificater ce very intéressantac texto ?
[^] # Re: Instrumenter ?
Posté par case42 (site web personnel) . Évalué à 5.
Alors oui certes, il s'agit d'un néologisme qui n'existe pas dans le dictionnaire, mais encore une fois, le français est une langue vivante, pas une langue morte, on a le droit de forger de nouveaux mots, personne ne meurt quand on le fait, et ici réfléchir deux minutes sur le sens du mot plutôt que de se référer mécaniquement a un index forcement incomplet et obsolète permet de résoudre la difficulté , fou non?
[^] # Re: Instrumenter ?
Posté par guillaume teissier . Évalué à 4.
L'idée est de pouvoir obtenir des précisions sur le comportement d'un programme sans avoir accès au code source.
Les exécutables que tu peux trouver dans /usr/bin et /bin sous Linux sont majoritairement dynamiques. A chaque fois que tu lance un exécutable dynamique, le chargeur - dynamique - est appelé, pour résoudre les dépendances de bibliothèques. Ce chargeur offre dans ces versions les plus récentes un moyen de tracer l'appel de fonctions.
Le travail de latrace consiste à utiliser cette fonctionnalité du chargeur et afficher sous forme intelligible les données qu'il récupère.
[^] # Re: Instrumenter ?
Posté par Aissen . Évalué à 4.
Imaginons que tu instrumentes un programme comme "less":
$ ldd `which less`
linux-gate.so.1 => (0xb774b000)
libncurses.so.5 => /lib/libncurses.so.5 (0xb76fc000)
libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb75b5000)
libdl.so.2 => /lib/i686/cmov/libdl.so.2 (0xb75b0000)
/lib/ld-linux.so.2 (0xb774c000)
On voit ici le chargeur dynamique ld-linux.so. linux-gate.so n’est pas vraiment un bibliothèque partagée, mais plutôt une fonctionnalité exposée pas le noyau Linux.
"less" est donc linké avec les bibliothèques suivantes : libc, libncurses, et libdl. Chaque bibliothèque expose des méthodes (entre autres, tu peux les examiner avec objdump).
En instrumentant ld.so, latrace va permet d’examiner en temps réel tout ce qui se passe dans le programme, et ainsi de voir les appels à chaque fonction des bibliothèques dynamiques :
$ latrace less
19810 __libc_start_main [/lib/i686/cmov/libc.so.6]
19810 getenv [/lib/i686/cmov/libc.so.6]
19810 isatty [/lib/i686/cmov/libc.so.6]
19810 getenv [/lib/i686/cmov/libc.so.6]
19810 tgetent [/lib/libncurses.so.5]
19810 _nc_setupterm [/lib/libncurses.so.5]
19810 strlen [/lib/i686/cmov/libc.so.6]
19810 isatty [/lib/i686/cmov/libc.so.6]
19810 calloc [/lib/i686/cmov/libc.so.6]
19810 _nc_read_entry [/lib/libncurses.so.5]
19810 sprintf [/lib/i686/cmov/libc.so.6]
19810 _nc_pathlast [/lib/libncurses.so.5]
19810 strrchr [/lib/i686/cmov/libc.so.6]
[…]
19810 getenv [/lib/i686/cmov/libc.so.6]
19810 strlen [/lib/i686/cmov/libc.so.6]
19810 calloc [/lib/i686/cmov/libc.so.6]
19810 snprintf [/lib/i686/cmov/libc.so.6]
19810 write [/lib/i686/cmov/libc.so.6]
Missing filename ("less --help" for help)
19810 fsync [/lib/i686/cmov/libc.so.6]
19810 tcsetattr [/lib/i686/cmov/libc.so.6]
19810 exit [/lib/i686/cmov/libc.so.6]
19810 __cxa_finalize [/lib/i686/cmov/libc.so.6]
19810 __cxa_finalize [/lib/i686/cmov/libc.so.6]
less finished - exited, status=0
Note: "ldd" exécute du code présent dans le binaire, et n’est donc pas adapté à de l’analyse forensique. Lui préférer "objdump" :
$ objdump -p `which less` |grep NEEDED
NEEDED libncurses.so.5
NEEDED libc.so.6
[^] # Re: Instrumenter ?
Posté par ǝpɐןƃu∀ nǝıɥʇʇɐW-ǝɹɹǝıԀ (site web personnel) . Évalué à 4.
Troisième sens avéré du mot instrumenter :
« III. INDUSTR. PÉTROLIÈRE, emploi trans. ,,Doter une installation de raffinage d'appareils de contrôle automatiques. Instrumenter une colonne, un four`` (Lar. encyclop., Lar. Lang. fr.).»
Qui sait si d'ici quelques années on ne trouvera pas dans cet encyclopédie de la langue française une citation du journal ci-dessus attestant de l'emploi du verbe instrumenter en informatique :-). En attendant cet usage paraît bien cohérent.
« IRAFURORBREVISESTANIMUMREGEQUINISIPARETIMPERAT » — Odes — Horace
# pour ceux qui, comme saint thomas, ne croient que ce qu'ils voient
Posté par guillaume teissier . Évalué à 4.
Attention, la compilation de latrace nécessite d'avoir flex, bison, et autoconf. Avoir le paquetage binutils-dev installé est optionnel.
$ wget http://people.redhat.com/jolsa/latrace/dl/latrace-0.5.9.tar.(...)
$ tar xfj latrace-0.5.9.tar.bz2
$ cd latrace-0.5.9
$ aclocal && autoconf && ./configure && make && sudo make install
latrace est maintenant installé dans /usr/local.
Compilation d'un exécutable dynamique multithreadé
le fichier C suivant est tiré de l'échange de mail en lien sur la dépêche.
$ cat > test.c << EOF
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void *thread(void *i)
{
pthread_t t2,t3;
printf("In thread\n");
printf("thread PID %d\n", getpid());
sleep(5);
pthread_exit(0);
}
int main(int argc, char **argv)
{
pthread_t t1, t2;
printf("main PID %d\n", getpid());
pthread_create(&t1, NULL, thread, NULL);
pthread_create(&t2, NULL, thread, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("threads joined\n");
return 0;
}
EOF
$ gcc -o test test.c -lpthread
$ ./test
main PID 27180
In thread
thread PID 27180
In thread
thread PID 27180
threads joined
ltrace en action pour tracer les appels à sleep:
$ ltrace -e sleep ./test
main PID 27228
In thread
thread PID 27228
+++ killed by SIGTRAP +++
Après avoir lu le man de ltrace, l'option -f permet de suivre les processus fils forkés :
$ ltrace -e sleep -f ./test
main PID 27237
ltrace reste bloqué, vous pouvez le tuer avec ctrl+c, ctrl+z puis kill -9 %1.
À latrace de jouer maintenant :
$ latrace -s sleep ./test
main PID 27204
In thread
thread PID 27204
In thread
thread PID 27204
27205 sleep [/lib/i686/cmov/libc.so.6]
27206 sleep [/lib/i686/cmov/libc.so.6]
threads joined
./test finished - exited, status=0
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.