Makefile
. Le programme trier
prend des nombres entiers en argument, séparés par des espaces. Exécutez les expériences suivantes (vous pouvez avoir des résultats différents sur votre machine, car ce programme est buggé) :
~>trier 5 9 3 après tri: 3 5 9ce qui a l’air de marcher... Mais avec d’autres jeux d’essai, en mettant 4 ou 5 arguments dont certains négatifs ou au contraire très grands (1 million), vous constaterez l’apparition de valeurs intruses dans les résultats. En suivant la démo faîte par votre enseignant sur les fonctionnalités de base de
ddd
, vous trouverez la cause du problème en tapant les mêmes commandes que lui sur votre machine.ddd trier &
et suivez les instructions de votre enseignant. Cette démo est celle indiquée par Andreas Zeller dans son manuel de ddd.
ls
. La raison est que votre shell est dans un état où l’écriture des fichiers core est interdite. Tapez la commande ulimit -c. Elle affiche la taille maximum autorisée pour un fichier core. Si elle est nulle, cela interdit son écriture. Tapez alors la commande ulimit -c 1000000
pour autoriser l’écriture de fichiers core jusqu’à un million d’octets et rééxécutez le programme tfile1
. Cette fois, vous obtenez le message segmentation fault (core dumped) et constatez l’apparition d’un fichier core¹.adb
, gdb
(debuggers CLI - Command Line Interface) ou dbx
, ddd
(debuggers graphiques). ddd
utilise gdb
par défaut pour analyser les fichiers core. Lancez ddd
en indiquant le fichier binaire du programme à analyser et le fichier core produit :
# Sous Linux , tapez la commande suivante avec complétion pour faire apparaître XXX : ~> ddd tfile1 core.XXXLa fenêtre du bas indique l’adresse du plantage dans le code source. Avec les commandes élémentaires de
ddd
, vous pouvez facilement :
nbPlaces
qui plante;
fi
et constater qu’elle est nulle, ce qui explique l’erreur d’adressage mémoire lors du déférencement du pointeur;
creer
. Pour cela placez un point d’arrêt (breakpoint) au début de cette routine. Exécutez en pas à pas son fonctionnement et suivez l’évolution des valeurs des variables f
et fi
. Vous constatez qu’on sort de la routine avant d’avoir appelé malloc
. En examinant le code, vous en trouverez la cause : une faute de frappe classique, dénoncée par les livres de programmation en langage C...
tfile1
, sans utiliser check. Le programme file1.c contient un bug qui fait fait échouer le programme de test, mais sans plantage et donc sans production d’un fichier core. Avec ddd
, il faut trouver le bug, le corriger et vérifier que les tests sont alors sans erreur.Makefile
et repérez le numéro de ligne de l’échec (31).
tfile1
.
sor.info
vaut "e2" au lieu de "e1"). Le problème vient donc du dernier appel à sortir
.sortir
(ligne d’au dessus) et relancez l’exécution.
sortir
. Exécutez ensuite sortir
en mode pas à pas.
fi
et en double-cliquant sur sa représentation, faite apparaître sa valeur en mode vertical (avec les noms des champs). Vous trouvez que la file a trois places, trois éléments et les curseurs entree=2 et sortie=0.
fi->mem[fi->sortie]
(tapé dans le tampon d’entrée, après l’avoir vidé par ()). Vous trouvez "e2", la valeur qui est sortie. Donc sortir
fonctionne apparemment de façon correcte et le problème doit venir de l’état de la représentation de la file fi
. Il faut donc inspecter le fonctionnement de entrer
.entrer
. Comme précédemment, dépliez le contenu de fi
avec des doubles clics. Vous voyez ainsi apparaître le contenu de FileImpl
avec ses champs. Si vous double-cliquez sur mem
, vous affichez fi->mem[0]
. Pour afficher les autres valeurs du tableau mem
, il faut:
fi->mem[1]
et fi->mem[2]
,
fi->mem[0..2]
.
Les champs info
ont des adresses nulles (en rouge).
until
). Lorsque vous quitterez la routine entrer
, l’affichage des variables disparaîtra. Mais dès que vous entrerez à nouveau dedans, il réapparaîtra. Vous pouvez ensuite poursuivre l’exécution en pas à pas et observer les changements de valeur des champs de FileImpl
. En réfléchissant aux valeurs que devraient avoir ces différents champs, vous trouverez facilement quel champ est incorrect et donc quelle instruction de la routine entrer
est incorrecte. Corrigez l’erreur, relancez le test et concluez.
Makefile
. Ce répertoire contient la version 2 de la file, comme dans le TP de synthèse, mais avec un petit programme de test et deux erreurs d’implémentation à trouver avec ddd
. Cette expérience devrait vous convaincre qu’il ne faut utiliser un debugger que lorsqu’il n’y a aucune autre solution. L’utilisation d’assertions exécutables évite le debugging...ddd
comme les autres routines du programme à tester, ce qui nécessite de les sauter lors des exécutions en pas à pas. Une solution à ce problème est d’écrire un programme de test sans check, comme ci-dessus ou de changer la définition des macros de check pour les rendre inoffensives.
I | Attachment ![]() | Action | Size | Date ![]() | Who | Comment |
---|---|---|---|---|---|---|
![]() | Fourniture6.tbz | manage | 6.6 K | 09 Mar 2008 - 15:08 | NicolasNobelis | Fourniture pour le TP6 |
![]() | corrige06.pdf | manage | 41.0 K | 15 Mar 2008 - 20:44 | NicolasNobelis | Corrigé du TP6 |