Devoir Système - 1999-2000
Traceur de processus en temps réel
©
M. Laporte - D. Mathieu
mathieu@romarin.univ-aix.fr
I.U.T.d'Aix en Provence - Département Informatique

Sommaire
Sujet
Clients
Traceur
Organisation
Travail à rendre
Sujet : traceur de processus en temps réel.
Le traceur est un programme qui doit fonctionner de la façon suivante : plusieurs processus (que l’on nommera dorénavant simplement clients) lui envoient toutes les informations concernant leur exécution (trace).
Le traceur peut afficher ces informations ou les filtrer selon les désirs de l’utilisateur.
Ce mécanisme ne devra être activé que lorsque les programmes clients auront été compilés avec la macro TRACE_ON (cf. TP fichiers : "écriture immédiate").
Le lancement de l'ensemble doit pouvoir être effectué à partir d'une commande ressemblant à celle-ci :
-
duo$>traceur client1 [<parametres>]
[client2 [<parametres>]...]
|
Bien entendu, vous pouvez l'améliorer ou la modifier selon vos besoins.
Sommaire
Clients
Outre les flux standard cin, cout, et cerr, correspondant aux file descriptors 0, 1, 2, le flux de sortie cdump (file descriptor = 3) doit avoir été ouvert lorsque les clients commencent leur exécution.
L’objet cdump doit présenter toutes les caractéristiques d’un ofstream.
C’est dans ce flux que les clients injectent tous les éléments de la trace, par exemple :
-
cdump << "processus
de pid : " << getpid() << ... ;
|
Deux sortes d’informations sont émises, qui décrivent soit l’état des objets, soit le déroulement des fonctions.
Pour que le traceur puisse les identifier et les traiter, chaque émission (une seule ligne) doit commencer par une entête.
Trace de fonction :
-
cdump << "pid : "
<< getpid() << "; fonction : SaveSig() "
// entete
-
<< "; etape 1"
-
<< endl ;
|
ou
-
cdump << "pid : "
<< getpid() << "; fonction : SaveSig() "
// entete
-
<< "; ASauvegarder = " << ASauvegarder
-
<< endl ;
|
Trace d'objet :
Un objet ne peut être "dumpé" que si la classe à laquelle il appartient contient la fonction membre Dump().
Soit par exemple la hiérarchie de classes "dumpables" suivante :
-
class CA : public ... {
... };
-
class CB : public CA
{ ... };
-
class CC : public CB
{ ... };
|
figure 1
Le "dump" d'un objet consiste à afficher son état, c'est-à-dire les valeurs de toutes ses parties constitutives (objet de sa classe mère et données membres éditables).
Deux possibilités peuvent être envisagées lorsqu'une donnée membre est elle-même une instanciation (un objet) d'une autre classe : ou bien elle dispose d'une surcharge de l'opérateur injecteur <<, ou bien la classe est elle-même "dumpable".
Toute fonction Dump() d'une classe dérivée devrait commencer par appeler la fonction Dump() de sa classe mère.
Une utilisation simple peut être par exemple la suivante (suite aux déclarations de la figure 1) :
-
CB a (1);
-
CB b (11, 12);
-
CC c (111, 222, 333);
-
cdump << "pid : "
<< getpid()
// entete
-
<< "Dump de l'objet a : " << endl;
-
a.Dump ();
-
cdump << "pid : "
<< getpid()
// entete
-
<< "Dump de l'objet b : " << endl;
-
b.Dump ();
-
cdump << "pid : "
<< getpid()
// entete
-
<< "Dump de l'objet c : " << endl;
-
c.Dump ();
|
figure 2
On imagine alors la complexité d'une trace dans le cas de dérivations multiples et nombreuses.
L'utilisateur doit donc pouvoir limiter la profondeur de la trace : fixer le nombre de niveaux de dérivations que le dump doit remonter.
Une solution consiste à doter le flux cdump d'une donnée membre, par exemple m_Depth, qui peut par exemple être utilisée de la façon suivante (suite à la figure 2) :
-
cdump.SetDepth (1);
-
cdump << "pid : "
<< getpid()
// entete
-
<< "Dump leger de l'objet a : " << endl;
-
a.Dump ();
-
cdump << "pid : "
<< getpid()
// entete
-
<< "Dump leger de l'objet b : " << endl;
-
b.Dump ();
-
cdump.SetDepth (2);
-
cdump << "pid : "
<< getpid()
// entete
-
<< "Dump partiel de l'objet c : " << endl;
-
c.Dump ();
|
figure 3
Dans cet exemple, seules les données membres de la classe de l'objet sont affichées (et non ceux des classes mères) pour l'objet a et b, alors que les données membres des classes CB et CC sont affichées pour l'objet c.
Inversement, l'exemple de la figure 4 provoquerait l'affichage complet :
-
cdump.SetDepth (-1);
-
cdump << "pid : "
<< getpid()
// entete
-
<< "Dump complet de l'objet c : " << endl;
-
c.Dump ();
|
figure 4
Sommaire
Traceur
1ère version : affichage direct
Le traceur se contente d’afficher toutes les informations qu’il reçoit, sans aucun traitement complémentaire.
2ème version : affichage à filtrage statique
Au début de son exécution, le traceur lit au clavier les directives lui permettant de filtrer les informations qu’il affiche.
Par exemple, filtrage sur le n° de pid, le nom de la fonction, de la classe, etc… On peut éventuellement imaginer un filtrage "générique", c'est à dire utilisant les caractères spéciaux comme ? et *.
3ème version : affichage à filtrage dynamique
Le traceur peut être interrompu à tout moment par un signal.
Il passe alors en mode "saisie" (en proposant éventuellement un menu - le plus simple possible ) par lequel l’utilisateur peut ajouter ou modifier les directives de filtrage.
L’effet de la modification doit être immédiat.
4ème version : affichage à filtrage (statique ou dynamique) utilisant un tampon circulaire
Le traceur est constitué de deux processus, l’un qui effectue comme ci-dessus le filtrage (le "filtre"), et qui écrit les résultats dans un tampon circulaire, l’autre qui lit le tampon circulaire et en affiche le contenu ("l’afficheur").
Cette solution n’a d’intérêt que pour préparer la dernière version.
5ème version : affichage à filtrage (statique ou dynamique) utilisant un tampon circulaire avec recouvrement :
Lorsque le tampon est plein, le processus "filtre" écrase les données les plus anciennes dans le tampon.
L’effet de la modification doit toujours être immédiat.
L'intérêt de cette méthode est de ne conserver que les trames les plus récentes, afin de ne pas saturer l'ensemble.
Il est évident que l'utilisateur devrait pouvoir, à son gré, choisir dynamiquement le mode de tampon circulaire (avec ou sans recouvrement).
Remarques
La classe ofstream possède un constructeur auquel on peut passer en paramètre le file descriptor d'un fichiers déjà ouvert (en écriture, bien entendu !).
Il est alors possible d'écrire "normalement" dans ce flux (au moyen d'un injecteur).
Toute classe peut être dérivée (y compris la classe ofstream).
Sommaire
Organisation
Après quelques jours de réflexion, vous devez commencer à imaginer la structure de votre devoir, les outils que vous utiliserez, ce que vous vous sentez capables de faire, etc...
Vous devez ensuite vous répartir rapidement le travail de façon équitable, spécifier au mieux les fonctions de chacun, quitte à faire évoluer ces spécifications au fur et à mesure des besoins.
PRENEZ DES NOTES ! Fixez-vous un calendrier prévisionnel de réalisation.
Si vous devez utiliser des outils de système non maîtrisés par exemple, essayez de ne pas être tous bloqués et de mener plusieurs activités en parallèle, quitte à court-circuiter provisoirement certaines parties (un sleep() remplaçant une action, une lecture au clavier remplaçant l'attente d'un événement quelconque, etc...)
Le travail demandé se prête particulièrement à un développement en parallèle dont la décomposition est assez facile.
De même il peut être mis au point par étapes successives.
Par exemple, dans un premier temps, le flux cdump peut être tout simplement le flux cout.
De même, la notion de profondeur peut provisoirement être stockée dans une variable globale, etc...
Cela permet à chaque étudiant de développer des parties de programme indépendamment.
Pour la mise au point du traceur, et en attendant que les problèmes de cdump et de connexion soient réglés, il est aussi suggéré d'utiliser des fichiers d'entrée, générés à la main.
De même, il est peut-être plus simple, dans un premier temps, de tracer un seul processus que d'en tracer plusieurs.
Vous pouvez vous créer un protocole de communication entre les clients et le traceur, en convenant d'une structure d'entête de trame qui aurait un format fixe contenant des informations comme par exemple le numéro de pid du processus (déjà signalé plus haut), l'heure d'émission, un code indiquant la nature de l'information : commentaire, indicateur de passage (dans une partie de code : un bloc "alors", un cas d'un schéma de choix, etc...), valeur d'une variable locale, valeur de retour d'une fonction, etc...
Toutes les parties des TPs de système peuvent être utilisés : fichiers, signaux, processus fils, pipes, redirection, exécution de commandes, etc...
On peut même imaginer un timer qui réveillerait le traceur lorsqu'il ne reçoit plus d'informations des clients (qui seraient par exemple dans une boucle infinie, interbloqués ou dans une situation bloquante (pause(), etc...).
Vous pouvez (devez) donc récupérer tous les outils, développés pendant les TPs, que vous jugerez utiles, modifier (ou même corriger si nécessaire) à votre guise tous les corrigés qui vous ont été donnés, tant en seconde qu'en première année.
N'hésitez pas à créer des classes si elles vous paraissent nécessaires, mais ne vous forcez pas à en faire si cela ne vous paraît pas naturel.
C'est avant tout un devoir de Système !!! Passez le moins de temps possible à la qualité de l'affichage : il constituerait à lui seul un travail spécifique de programmation d'I.H.M., ce qui est hors–sujet.
Commencez le plus vite possible, afin de voir venir les problèmes, rédigez en parallèle : PRENEZ DES NOTES ! N'hésitez pas à nous soumettre vos difficultés avant d'avoir perdu trop de temps.
Nous essaierons de vous aider à condition que vous fassiez l'effort de respecter la présentation.
Sommaire
Travail à rendre
Chaque fin de semaine, vous devez fournir les documents suivants :
-
semaine 1 : sur ½ page environ, le planning prévisionnel et les premiers tests effectués,
-
semaine 2 : sur ½ page à 1 page, l'état d'avancement de votre travail (entre autre le temps passé)
-
semaine 3 : sur ½ page à 1 page, l'état d'avancement de votre travail (temps passé)
-
semaine 4 : le rapport final.
Votre travail donnera lieu a la rédaction d'un rapport en deux parties :
-
le texte du rapport lui-même
-
les listings.
Le texte
Le texte a différents objectifs.
Il doit vous permettre de présenter globalement votre travail, afin de nous permettre de nous y retrouver plus facilement dans les listings.
Pour cela, vous devez expliquer le plus clairement comment vous avez compris le sujet, ce que vous avez traité.
Vous devez faire une présentation rapide de votre travail, comment il est structuré, comment l'ensemble fonctionne.
Quand vous estimez avoir donné suffisamment d'informations pour nous permettre d'entrer dans votre réalisation, vous devez développer plus précisément les points qui vous paraissent importants, difficiles, ou que vous jugez intéressants à mettre en valeur.
Nous sommes aussi intéressés par la façon dont vous vous êtes organisés, par les difficultés que vous avez rencontrées et la façon dont vous les avez surmontées.
Le sujet est très ouvert, vous pouvez donc imaginer de nombreux perfectionnements à votre travail, des généralisations, d'autres façons de résoudre le problème.
Cela nous intéresse, même si vous n'avez pas mené la réflexion jusqu'à la réalisation, à condition que vous ayez un peu pensé à la mise en oeuvre !
Enfin, nous aimerions un bilan de ce travail.
Pour résumer, le texte doit contenir les informations suivantes :
-
couverture indiquant les noms/groupes des auteurs et le titre,
-
sommaire paginé,
-
sommaire paginé des fichiers et des principales fonctions,
-
une analyse rapide de votre application (les différentes parties),
-
le planning prévisionnel, établi dès les premiers jours,
-
le planning effectif, mettant en évidence les raisons des écarts entre les deux
-
vos difficultés, trouvailles et autres,
-
ce qui marche et ce qui ne marche pas (mais comment vous aviez prévu de le faire),
-
vos choix motivés de conception et d’implémentation,
-
l’organisation générale de votre travail, en terme de processus, structures de données et de contrôles,
-
un mode d'emploi indiquant les différentes possibilités, destiné à un utilisateur moyen
-
une présentation détaillée de votre travail, vos choix justifiés entre plusieurs possibilités,
-
l'organisation (la hiérarchie) des fichiers créés,
-
un bilan (ce qui manque, le temps que vous avez passé, vos frustrations et satisfactions éventuelles, etc...)
Les pages doivent être numérotées.
Attention : n’utilisez pas des polices de caractères trop grandes, des interlignes immenses, des changements de page abusifs pour que le rapport soit gros, donc pour essayer de nous faire croire que le travail est important ! ...
Sommaire
Les listings
Les listings :
En résumé, tout ce qui peut mettre en valeur votre travail PERSONNEL... et rendre la correction la plus agréable et la plus facile.
Merci pour nous!
Sommaire
© D. Mathieu
mathieu@romarin.univ-aix.fr
I.U.T.d'Aix en Provence - Département Informatique