Introduction▲
Il y a quelques mois, j'ai suivi un cours sur TotalView, grâce à mon employeur. Maintenant, je suis complètement accro et quand je débogue une application parallèle, je n'utilise que lui. J'aimerai partager un peu l'expérience que j'ai eue avec cette bête.
Tout d'abord, TotalView n'est pas qu'un débogueur disponible sur les plateformes Unix et Linux. C'est aussi un vérificateur de mémoire (avec MemoryScape sous la forme d'un plugin) et un débogueur inverse (ce qui veut dire qu'on peut revenir en arrière lors du débogage, même quand le programme a crashé et que la pile des appels est détruite, ce que ne peut pas faire gdb).
I. Le débogueur parallèle▲
Dans la fenêtre principale de TotalView, chaque programme avec ses threads et ses processus peut être sélectionné, réouvert, même si la fenêtre du débogueur pour l'application est fermée. Le seul inconvénient est qu'il n'est pas possible de supprimer une application de cette fenêtre…
Lors du lancement de TotalView, une fenêtre d'ouverture de programme est ouverte. Il est possible de lancer un nouvel exécutable, de s'attacher à un processus ou de déboguer un fichier core. Si l'application utilise MPI, cela doit être indiqué (les implémentations usuelles sont supportées : mpich, mpich2, openmpi, mpt…).
Une fois l'application lancée, il est possible de la déboguer. L'interface montre quel processus et thread est en cours de débogage (la liste des processus et threads est disponible dans la zone des onglets en bas de la fenêtre). Malheureusement, il n'y a pas possibilité d'explorer le code, donc il faut parcourir à partir de la fenêtre principale et en double-cliquant sur le nom des fonctions son code pour placer un point d'arrêt quelque part.
Pour TotalView, les points d'arrêt sont un cas particulier des points d'action. Sur ces derniers, il est possible d'arrêter le programme ou exécuter un code simple. Il est aussi possible de dire à TotalView de s'arrêter au bout d'un certain nombre de passages sur l'instruction (pratique pour vérifier une erreur qui se déclenche à la centième itération).
Il y a plusieurs manières de s'arrêter à un point d'action : stopper tout dès qu'un processus ou thread atteint le point, ou les arrêter lorsqu'ils sont tous au point d'action, idem pour un groupe… Il y a un certain nombre de fonctionnalités très pratiques.
L'exploration des variables est l'une des utilisations courantes d'un débogueur. TotalView permet de rentrer (dive) dans une variable puis de l'explorer. Une variable multidimensionnelle peut être découpée et comparée entre processus. Lorsqu'une variable est modifiée, elle apparaît en jaune. Il est par exemple possible de comparer le résultat d'un échange MPI par ce biais.
En comparaison avec d'autres débogueurs parallèles (comme DDT), l'affichage des tableaux 2D est pauvre. TotalView a d'autres avantages pour combler cette lacune, comme avoir son propre moteur de débogage, sans se baser sur gdb.
II. MemoryScape et son plugin pour TotalView▲
MemoryScape est l'outil de gestion mémoire de TotalView. Il capte les appels à l'OS pour la mémoire et observe ce que fait l'application.
La première option est de surveiller (« guard ») les blocs mémoire. Cela est moins efficace que la vérification des bords de Fortran, mais cela coûte moins cher (les gardes mémoire ne sont vérifiés que lorsque le programme s'arrête ou si l'application est stoppée). D'autres options incluent les blocs peints (un motif est peint dans le bloc au lieu d'être initialisé à 0, et si ce motif apparaît quelque part, c'est que la donnée a été utilisée sans initialisation explicite), « hoarded » mémoire (la mémoire désallouée n'est pas libérée immédiatement, ce qui permet de détecter des corruptions de la mémoire) et naturellement les fuites mémoire.
Plusieurs graphiques peuvent être dessinés, mais certains peuvent être déroutants (comme le camembert mémoire qui ne montre pas la vérité).
III. ReplayEngine▲
ReplayEngine est un débogueur inverse (il permet de « rembobiner une exécution »). Lorsque le programme plante, il est possible de revenir en arrière pour trouver où le problème s'est effectivement produit.
Naturellement, l'option de rembobinage est basée sur des captures du programme (sauvegarde de la pile, des données contenues en mémoire…), ce qui signifie qu'il n'est pas possible de rembobiner un programme utilisant beaucoup de mémoire (plusieurs gigaoctets de mémoire), ou que le ReplayEngine choisit les moments où effectuer une capture, et il est possible que l'instant nécessaire à reproduire son erreur ne soit pas capturé. Je n'ai jamais utilisé ReplayEngine en raison ces deux inconvénients (tout débogueur inverse les possède).
Conclusion▲
Bien que cher, TotalView est extrêmement utile. Lorsque j'ai dû paralléliser avec MPI un code scientifique, TotalView a pu prendre en charge la bibliothèque MPI pour le lancement, et l'affichage des variables m'a permis de résoudre rapidement les communications.
Je n'ai jamais eu une réelle utilité à MemoryScape. La détection des fuites est efficace, mais comme pour Valgrind, certaines fuites n'en sont pas. La mémoire surveillée aurait pu m'être utile, mais mes bogues étaient des erreurs de lecture, donc elle ne sert pas.
En conclusion, je recommande l'utilisation de TotalView comme débogueur parallèle. En conjonction avec un profiler parallèle/MPI, c'est l'un des outils à posséder.
Site officiel du logiciel : http://www.totalviewtech.com/