7.1. Introduction
Les erreurs de programmation (segmentation fault, bus error etc...) ne seront pas facilement repérables une fois le bloc compilé (bien souvent, ceci conduit à planter Ptcl (PigiRpc-Shell)). Pour débugger, il est possible de lancer 'pigi' en indiquant l'option `-debug'.Cela permet de se faire une idée beaucoup plus précise de ce qui génère une erreur (cf chapitre du `Programmer's manual'), car vous pouvez exécuter le code pas à pas et examiner le contenu des variables et de la mémoire à tout moment. De plus le débuggueur est souvent capable, si tous vos fichiers sources ont été compilés en mode debug de vous donner la ligne et l'instruction sur laquelle le programme se plante.
Attention notamment aux problèmes d'allocation mémoire! Ptolemy est un gros programme lui-même et il ne pardonne pas du tout les oublis d'allocation ou de désallocation. En ce qui concerne les données transmises entre étoiles, il suffit de les créer et Ptolemy désallouera quand cela sera nécessaire. Par contre, si vous avez alloué à l'intérieur d'une étoile un tableau ou une structure de données (par exemple une image contenant des résultats intermédiaires) il ne faut pas oublier de le détruire quand elle n'est plus nécessaire à la fin de la routine 'go' ou dans le 'wrapup'.
La structure de Ptolemy permet et encourage le test individuel de chaque étoile en utilisant des générateurs adaptés et en visualisant la sortie ou en la stockant dans un fichier. Il est important et judicieux de respecter cette philosophie de programmation puis de test immédiat.
7.2. Exemple.
L'exemple choisi ici réalise un filtrage linéaire bi-dimensionnel classique. Il permet également d'illustrer la notion d'objet de type 'message'. La description a été écrite en langage Ptolemy et a été volontairement bugguée.Le fichier se nomme SDFFiltre2d.pl. Le listing de ce fichier est donné plus loin.
Générer une étoile à partir de cette description. Puis l'insérer dans un schéma contenant un bloc 'ReadImage' en entrée et un bloc 'DisplayImage' en sortie. Vous trouverez ces 2 blocs dans la palette 'Image and Video processing' dont un sous-ensemble est illustré ci-dessous:

Sauvegarder le schéma et lancer la simulation: le programme s'arrête sur une erreur mémoire: 'Segmentation Fault...'
Le schéma de simulation est illustré ci-dessous.
Le listing du fichier de description est donné ci-dessous.
//////////////////DEBUT DU LISTING////////////////////
defstar {
name { Filtre2d }
domain { SDF }
version { %W% %G% }
author { cathy }
copyright{
}
location { SDF User library }
desc {
Filtre une image (applique une matrice de filtrage sur l'image).
}
// permet de faire un ou plusieurs include de fichiers
// definition des types matriciels
hinclude { "Matrix.h" }
input {
name { input }
type { FLOAT_MATRIX_ENV }
desc { Image en entrée (niveau de gris) }
}
output {
name { output }
type { FLOAT_MATRIX_ENV }
desc { Image en sortie (niveau de gris) }
}
defstate {
name { coefs }
type { floatarray }
default { "0.25 0.25 0.25 0.25" }
desc { Coefficients de la matrice de filtrage }
}
defstate {
name { sizeX }
type { int }
default { 2 }
desc { Taille de la matrice (nombre de coefts par ligne) }
}
defstate {
name { sizeY }
type { int }
default { 2 }
desc { Taille de la matrice (nombre de lignes) }
}
defstate {
name { DefaultValue }
type { float }
default { 128.0 }
desc { Valeur par default au bord de l'image }
}
go {
int i,j,mx,my,ky,kx,sx,sy,pos_x,pos_y;
double s,pix_value;
/* Une "FloatMatrix " est un type de donnee particulier */
/* Il passe d'une etoile a une autre a l'interieur d'une */
/* enveloppe. Pour etre utilisee, l'image doit etre extraite */
/* de l'enveloppe. Ce qui suit est du C++, le reste d'une etoile */
/* peut etre totalement ecrit en C pur. */
Envelope envp;
// Application de la fonction get Message
// a l'objet input%0 pour recuperer l'enveloppe.
(input%0).getMessage (envp);
// Ensuite on verifie que dans l'enveloppe il y avait bien
// une "FloatMatrix "
TYPE_CHECK(envp, "FloatMatrix");
// On affecte le contenu de l'enveloppe a une variable
const FloatMatrix* imD = (const FloatMatrix*) envp.myData();
// Creation et initialisation de l'image resultat
// a la bonne taille
FloatMatrix * imgData =
new FloatMatrix(imD->numRows(), imD->numCols());
// Pointeur de parcours des pixels
double* d = &(imgData->entry(0));
const double* p = &(imD->entry(0));
// Determination du centre du filtre
mx=int(sizeX-1)/2;
my=int(sizeY-1)/2;
// taille de l'image
sx=int( imD->numCols() );
sy=int( imD->numRows() );
for (i = 0; i <= sy ; i++)
for (j = 0; j <= sx ; j++) {
s = 0;
// calcul de la reponse du filtre en un point
for (ky=0;ky<int(sizeY);ky++) {
for (kx=0;kx<int(sizeX);kx++) {
// Si le point multiplie par le coeff. courant est
// dans l'image d'entree, alors on l'utilise
// Si le point est hors ecran alors on utilise une
// valeur par
// defaut.
pos_y= i+ky-my;
pos_x= j+kx-mx;
pix_value= ( (pos_y>=0)&& (pos_y<=sy)&& (pos_x>=0)&& (pos_x<=sx) ) ? p[pos_x + sx * pos_y] : (double)DefaultValue ;
// multiplication par le coefficient du filtre
s += pix_value * coefs[kx+sizeX*ky];
} // end for kx
} // end for ky
// Assignation de la valeur au pixel de sortie
// apres seuillage entre 0 et 255
*d++ = (( s<0 ) ? 0 : ((s>255) ? 255 : ((double)s))) ;
} // end for j
// implicit end for i
// L'image resultat est mise dans une enveloppe
Envelope envp2(*imgData);
// L'enveloppe est envoyee a la sortie output
output%0 << envp2;
} // end go
} // end Filtre2d
7.3. Simulation
Après avoir créer l'étoile et l'avoir insérée dans le schéma de test, lancer la simulation: en cours de traitement l'exécution s'arrête avec le message d'erreur: " ... Segmentation Fault...". Quitter alors Ptolemy pour le relancer en mode debug:>> pigi -debugSi vous n'utilisez que des étoiles du domaine SDF ou DE, vous pouvez lancer "Ptiny", qui est une version réduite de Ptolemy où seuls les domaines SDF et DE ont été compilés:
>> ptiny -debugL'intérêt d'utiliser "Ptiny" est que son chargement est beaucoup plus rapide: vous optimisez ainsi le temps du cycle de debug.
"pigiRpc" démarre, puis la fenêtre du debuggueur graphique "ddd" apparaît. Un message vous informe qu'il y a un point d'arrêt sur la première ligne du "main" de pigiRpc. L'exécution s'arrêtera donc à cet endroit. Attendre d'avoir la main dans la fenêtre de console gdb du bas de ddd puis pour continuer l'exécution taper:
> cont
ou cliquer directement sur le bouton "cont".
Le déroulement du programme se poursuit et la fenêtre de bienvenue de Ptolemy apparaît. La fermer en cliquant sur "DISMISS".
Vous pouvez alors charger votre schéma et lancer l'exécution. En général, Ptolemy lance le chargement de l'étoile avant de lancer la simulation. Lorsque la fenêtre de contrôle "Run" apparaît, ne pas faire un "go", mais aller dans la fenêtre de contrôle du debuggueur et taper:
> CTRL-Cpour stopper l'exécution du programme. Vous pouvez alors mettre un point d'arrêt dans le code source de l'étoile, par exemple à la ligne 90:
> break SDFFiltre2d.pl:90Si gdb ne trouve pas le fichier source alors vous pouvez lui indiquer le répertoire où il se trouve :
> dir ~/mystar/srcContinuer l'exécution du programme par:
> contVous pouvez maintenant aller dans la fenêtre "Run" de ptolemy et lancer l'exécution en cliquant sur "go". Le programme s'arrête sur la ligne 90 et le listing du fichier '.pl' s'affiche. Xxgdb signale les points d'arrêt par des symboles rouges en forme de main. La ligne courante est signalée par une flèche bleue.
Continuer l'exécution pas à pas et observer comment varient les variables locales. Pour imprimer toutes les variables locales, entrer:
> info localsou cliquer sur le bouton "locals".
Vous pouvez rajouter ou supprimer d'autres point d'arrêts. Pour supprimer un point d'arrêt, examiner d'abord la liste des points d'arrêt par:
> info breakPuis repérer le numéro du point d'arrêt que vous voulez supprimer, par exemple le numéro 2. Ensuite taper:
> delete 2pour supprimer le point d'arrêt numéro 2.
Pour continuer l'exécution en "sautant" les 100 points d'arrêt suivants, taper:
> cont 100Si vous supprimez tous les points d'arrêt par:
> deleteet continuez l'exécution, le programme s'arrêtera sur la même erreur et vous indiquera l'instruction où se produit l'erreur. Ceci permet en général de déduire la source de l'erreur, par l'examen des variables locales:
> info localset/ou par l'examen de la pile d'appel des fonctions:
> whereLorsqu'il y a eu erreur de débordement mémoire, il est impossible de relancer la simulation du schéma seul. Il faut refaire un "run" complet:
> runVous pouvez éviter l'éxécution d'une étoile en plaçant un point d'arrêt au départ et en utilisant la commande return de gdb.
L'éventail des commandes possibles étant très large, nous vous invitons à vous référer à l'annexe pour y trouver d'autre types d'instructions.
![]() |
Précédent | Suivant | Plan | 13/03/00 | PTOLAB |

