grim7reaper

Un artisan du code

Outils de débogage pour la programmation concurrente — Valgrind

Valgrind est un logiciel sous licence GPLv2. Il a été développé à la base comme un outil pour déboguer les erreurs de gestion de la mémoire sous GNU/Linux. Par la suite, il a évolué pour devenir un véritable framework pour le développement d’outils d’analyse dynamique. Aujourd’hui, toute une suite d’outils est disponible et elle permet de :

Approche

Valgrind fonctionne en instrumentant le code. Cela signifie qu’il ajoute dynamiquement du code à exécuter en plus du code du programme en cours d’analyse afin de pouvoir le surveiller. Il y a deux façons d’instrumenter le code1 :

La seconde méthode est celle utilisée par Valgrind. Un de ses avantages est que le compilateur à la volée utilisé pour transformer le code intermédiaire en code machine peut donc également optimiser le code d’instrumentation.

Architecture

Valgrind est composé de trois grandes parties :

Instrumentation

La représentation intermédiaire utilisé par Valgrind est appelé VEX. C’est une représentation qui possède un typage, ne dépend pas de l’architecture utilisée (les instructions spécifiques à une architecture sont implémentées en tant que fonctions C) et qui est de la forme SSA (représentation où chaque variable est assignée une seule fois) qui est une représentation très utilisée dans les compilateurs car elle permet de transformer et optimiser le code (élimination de code mort par exemple) plus simplement.

Le processus d’instrumentation est composé de huit étapes :

Architecture et fonctionnement global de Valgrind

  1. désassemblage (le code machine du programme est converti en VEX) ;
  2. optimisation du code VEX ;
  3. instrumentation du code VEX par l’outil ;
  4. optimisation du code instrumenté ;
  5. construction de l’arbre à partir du code instrumenté (préparation pour l’étape suivante) ;
  6. conversion de l’arbre en liste d’instructions ;
  7. allocation des registres ;
  8. assemblage (la liste d’instructions est convertie en code machine).

Enfin, le code instrumenté est exécuté par le processeur. Selon les instrumentations réalisées, le code pourra émettre des évènements (accès mémoire à l’adresse X, allocation/libération de mémoire, appels système, …) à l’intention de l’outil.

Dans le prochain épisode…

Maintenant que l’on sait comment s’architecture Valgrind, on va pouvoir se pencher plus en détails sur le fonctionnement des outils qui nous intéresse dans le cadre de la programmation concurrente : Helgrind et DRD.


  1. Nethercote, N., and Seward, J. Valgrind: a framework for heavyweight dynamic binary instrumentation. In Proceedings of the 2007 ACM SIGPLAN conference on Programming language design and implementation (New York,NY, USA, 2007), PLDI ’07, ACM, pp. 89–100.