latrace, le traceur qui instrumente le chargeur dynamique

Posté par . Modéré par Nÿco.
Tags :
20
17
juin
2010
Linux
Le chargeur dynamique ld.so projette en mémoire les bibliothèques partagées référencées par un binaire. Pour ceux qui ont déjà décroché, lancez un terminal, et
ldd /bin/bash
listera 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 !
  • # Instrumenter ?

    Posté par . Évalué à  1 .

    Instrumenter : Dresser un contrat, procès-verbal. Orchestrer. Dictionnaire Le petit Robert

    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 (page perso) . Évalué à  5 .

      C'est marrant, sans me référer a un dictionnaire mais en utilisant mon cerveau (tm), je suis parvenu a déduire que dans ce contexte, le néologisme "instrumenter" devait être compris comment "équiper en instrument", c'est a dire, dans le contexte toujours, introduire dans le chargeur dynamique les mécanismes nécessaires a la récupération d'informations sur son etat, ses actions...

      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 . Évalué à  4 .

      Il faut rapprocher le sens d'instrumenter de celui de l'instrumentation cf wikipedia http://fr.wikipedia.org/wiki/Instrumentation_%28science%29.

      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 . Évalué à  4 .

      Ta définition n’est pas loin du compte. Tu instrumentes le chargeur dynamique (ld.so) pour voir ce qui se passe dans tes programmes. Cela permet de tracer l'appel et le retour de fonctions appartenant aux bibliothèques partagées.
      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 (page perso) . Évalué à  4 .

      Et maintenant prenons un (le) vrai dictionnaire de français : atilf. Que dit-il ?
      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.
  • # pour ceux qui, comme saint thomas, ne croient que ce qu'ils voient

    Posté par . Évalué à  4 .

    Compilation de latrace 0.5.9
    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 à ceux qui les ont postés. Nous n'en sommes pas responsables.