Documents pareils
ORACLE TUNING PACK 11G

Conduite et Gestion de Projet - Cahier des charges

Compte-rendu de projet de Système de gestion de base de données

Conditions : stage indemnisé, aide au logement possible, transport CEA en Ile-de-France gratuit.

Chapitre 1 : Introduction aux bases de données

2. RAPPEL DES TECHNIQUES DE CALCUL DANS R

Télécom Nancy Année

Évaluation et implémentation des langages

Baccalauréat technologique

RapidMiner. Data Mining. 1 Introduction. 2 Prise en main. Master Maths Finances 2010/ Présentation. 1.2 Ressources

Programmation Objet - Cours II

2. Activités et Modèles de développement en Génie Logiciel

LES CARTES À POINTS : POUR UNE MEILLEURE PERCEPTION

Cours Composant 2. Qualité logicielle et spécications algébriques

DÉVELOPPEMENT INFONUAGIQUE - meilleures pratiques

CRÉER UNE BASE DE DONNÉES AVEC OPEN OFFICE BASE

Conception de circuits numériques et architecture des ordinateurs

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

Rappel. Analyse de Données Structurées - Cours 12. Un langage avec des déclaration locales. Exemple d'un programme

Fiche méthodologique Rédiger un cahier des charges

CLAIRE, UN OUTIL DE SIMULATION ET DE TEST DE LOGICIELS CRITIQUES. Jean GASSINO, Jean-Yves HENRY. Rapport IPSN/Département d'évaluation de sûreté N 280

PROBLEMES D'ORDONNANCEMENT AVEC RESSOURCES

(VM(t i ),Q(t i+j ),VM(t i+j ))

PARCOURS COMPLET AU COURS MOYEN

Formation projet informatique. Expression de besoins, définir un besoin informatique

Annexe : La Programmation Informatique

Utilisation de l analyse statique comme outil d aide au développement. par. Yves Gauthier

TP : Shell Scripts. 1 Remarque générale. 2 Mise en jambe. 3 Avec des si. Systèmes et scripts

Université de Lorraine Licence AES LIVRET DE STAGE LICENCE

Architecture d'entreprise : Guide Pratique de l'architecture Logique

Problème : Calcul d'échéanciers de prêt bancaire (15 pt)

Diagramme de classes

LES OUTILS D ALIMENTATION DU REFERENTIEL DE DB-MAIN

Systèmes de transport public guidés urbains de personnes

Qu'est-ce que le BPM?

Grandes lignes ASTRÉE. Logiciels critiques. Outils de certification classiques. Inspection manuelle. Definition. Test

Méthodologies de développement de logiciels de gestion

modélisation solide et dessin technique

PRODIGE V3. Manuel utilisateurs. Consultation des métadonnées

Chapitre I : le langage UML et le processus unifié

Livre blanc Mesure des performances sous Windows Embedded Standard 7

TEXT MINING von 7

Introduction. I Étude rapide du réseau - Apprentissage. II Application à la reconnaissance des notes.

basée sur le cours de Bertrand Legal, maître de conférences à l ENSEIRB Olivier Augereau Formation UML

2 Grad Info Soir Langage C++ Juin Projet BANQUE

D'UN THÉORÈME NOUVEAU

La méthode des cas et le plan marketing : énoncé seul

Le génie logiciel. maintenance de logiciels.

Date : Tangram en carré page

NOTATIONS PRÉLIMINAIRES

LE PROBLEME DU PLUS COURT CHEMIN

IFT2255 : Génie logiciel

Business Intelligence avec SQL Server 2012

Méthodes de développement. Analyse des exigences (spécification)

Théories de la Business Intelligence

Ordonnancement. N: nains de jardin. X: peinture extérieure. E: électricité T: toit. M: murs. F: fondations CHAPTER 1

13 conseils pour bien choisir son prestataire de référencement

I. Introduction aux fonctions : les fonctions standards

Anticiper pour avoir une innovation d'avance : le leitmotiv de Pierre Jouniaux, entrepreneur du big data!

Les diagrammes de modélisation

Recherche dans un tableau

Deuxième partie. Approche globale d'implémentation d'un projet PLM

DA MOTA Anthony - Comparaison de technologies : PhoneGap VS Cordova

Éléments d'architecture des ordinateurs

O b s e r v a t o i r e E V A P M. Taxonomie R. Gras - développée

Rapport d'analyse des besoins

NORME INTERNATIONALE D AUDIT 260 COMMUNICATION DES QUESTIONS SOULEVÉES À L OCCASION DE L AUDIT AUX PERSONNES CONSTITUANT LE GOUVERNEMENT D'ENTREPRISE

Méthode universitaire du commentaire de texte

5 semaines pour apprendre à bien jouer un morceau de piano

FICHE S PEDAGOGIQUE S. Bilan personnel et professionnel Recherche active d emploi

Chapitre 2. Classes et objets

Brique BDL Gestion de Projet Logiciel

Vers l'ordinateur quantique

Les modules SI5 et PPE2

ANNEXE 1. Si vous souhaitez ajouter un descriptif plus détaillé de l offre à votre annonce, merci de le joindre accompagné de ce formulaire.

INTRODUCTION GENERALE...1 LA CONNEXION ODBC :...1. CONNEXION AU TRAVERS D EXCEL(tm)...6. LOGICIEL QUANTUM GIS (Qgis)... 10

3. SPÉCIFICATIONS DU LOGICIEL. de l'expression des besoins à la conception. Spécifications fonctionnelles Analyse fonctionnelle et méthodes

Service de réplication des données HP pour la gamme de disques Continuous Access P9000 XP

Cours Langage C/C++ Programmation modulaire

Série TD 3. Exercice 4.1. Exercice 4.2 Cet algorithme est destiné à prédire l'avenir, et il doit être infaillible! Exercice 4.3. Exercice 4.

ORACLE DIAGNOSTIC PACK 11G

Développement d'un projet informatique

Rappels sur les suites - Algorithme

Guide No.2 de la Recommandation Rec (2009).. du Comité des Ministres aux États membres sur la démocratie électronique

Réalisabilité et extraction de programmes

Année : Team-War Jaafar AMRANI-MESBAHI Fabien GARCIA Abdelali NAIT BELKACEM Rahma NAKARA Philippe NGUYEN

Date de diffusion : Rédigé par : Version : Mars 2008 APEM 1.4. Sig-Artisanat : Guide de l'utilisateur 2 / 24

Entrepôt de données 1. Introduction

INTELLIGENCE ECONOMIQUE : ENJEUX ET RETOUR D EXPERIENCE PILOTE DANS SEPT PMI DE BOURGOGNE

Sciences de Gestion Spécialité : SYSTÈMES D INFORMATION DE GESTION

PARAGON SYSTEM BACKUP 2010

Contrôle interne et organisation comptable de l'entreprise

Programmation d'agents intelligents Vers une refonte des fils de raisonnement. Stage de fin d'études Master IAD 2006

PRODIGE V3. Manuel utilisateurs. Consultation des métadonnées

Analyse de performance, monitoring

Logiciel Libre Cours 3 Fondements: Génie Logiciel

Langage HTML (2 partie) <HyperText Markup Language> <tv>lt La Salle Avignon BTS IRIS</tv>

Transcription:

Numéro d'ordre: D 00-09 THÈSE Présentée devant l'institut National des Sciences Appliquées de Rennes pour obtenir le grade de Docteur de l'insa de Rennes Mention informatique par Erwan Jahier Équipe d'accueil : Lande, IRISA École Doctorale : MATISSE Composante universitaire : Insa de Rennes Titre de la thèse : Analyse dynamique de programmes : mise en uvre automatisée d'analyseurs performants et spécications de modèles d'exécution soutenue le 15 Décembre 2000 devant la commission d'examen M. : Daniel Herman Président MM. : Baudouin Le Charlier Rapporteurs Pierre Deransart MM. : Dominique De Waleffe Examinateurs Olivier Ridoux Md. : Mireille Ducassé Directrice de thèse

À Nolwenn et Aziliz, mes deux gros cailloux.

Remerciements Le jury. Daniel Herman, Professeur à l'université de Rennes 1, est incontestablement la personne qui, par l'intermédiaire de son cours génie logiciel en seconde année de Deug, m'a donné l'envie de faire de l'informatique plus tard. Je suis donc particulièrement heureux qu'il m'ait fait l'honneur de présider ce jury. Je remercie Baudouin Le Charlier, Professeur à l'université de Namur, et Pierre Deransart, Directeur de recherche à l'inria, d'avoir accepté la charge de rapporteur. Je remercie également Dominique De Walee, Directeur technique de la société Mission Critical, et Olivier Ridoux, Professeur à l'université de Rennes 1, d'avoir participé au jury en tant qu'examinateurs. Je remercie enn Michel Van den Bossche, PDG de Mission Critical, dont j'ai grandement apprécié la présence lors de la soutenance. Les relecteurs de l'ombre. Un grand merci pour leur courage et leur abnégation aux relecteurs néophytes, Nolwenn et Yvon Cornec pour la partie en français, et Marcel Seaudreau pour la partie en anglais. Fabien Gaucher et Yvan Roux ont aimablement accepté de jeter un dernier un coup d'oeil à ce document avant son impression ; les erreurs typographiques, grammaticale et ortograques y restant sont donc, il va de soi, de l'entière responsabilité de ces derniers. Kangaroo land. Iwarmly thank Fergus Henderson for his wonderfull technical support and code reviews. I also thank the whole smashing Mercury group with which it was a real pleasure to work during those three years. During my rst year of Phd, I had the chance of spending one month of french winter in Melbourne summer; Zoltan Somogyi, Fergus Henderson, Thomas Conway, Tyson Down, Mark Brown, David Jeery, Lee Naish, and Harald Sondergaard made my stay oversees an unforgivable moment. I am especially gratefull to Lee and Harald for taking me away toa3daywalk that give me the occasion to see my only true wild kangaroo... which was dead along the road! Universités. J'ai passé une bonne partie de mes trois années d'aspirant docteur dans les locaux du département informatique de l'insa. J'ai eu l'occasion d'y côtoyer des gens adorables. Les secrétaires, Lucette Bohuon et Joëlle Leroyer ; les ingé-sys, Jean- Louis Neveu et Véronique Abily ; et des enseignants-chercheurs, tels Marie-Joe Pédrono, Pierre-Yves Glorennec et Yvan Leplumey, dont j'ai particulièrement apprécié la gentillesse. Je garde également un souvenir impérissable de la voix chaude et forte du résident en campagne du bureau d'en face ; un certain Yves Cochet. J'ai ensuite eectué une année d'ater à l'ifsic, où j'ai eu le bonheur de collaborer avec Yannick Letertre, Lucien Ungaro, César Viho, Gilles Lesventes et Jean-Christophe Engel. De tous, je garderai toujours le meilleur souvenir. Le groupe Lande. J'ai apprécié la compagnie de chacun des membres de cette ne équipe, que ce soit les permanents : Pascal Fradet, Thomas Genet et Jensen, Daniel Le Métayer, Florimond Ployette, et Olivier Ridoux ; ou bien les thésards, avec, par ordre de

2 disparition, Valérie Gouranton, Ronan Gaugne, Tommy Thorn, Valérie-Anne Nicolas, Julien Mallet, Lionel Van Aertryck, Sarah Mallet, Mickaël Périn, David Mentré ; et les suivants qui suivent : Marc Éluard, Siegfried Rouvrais, Frédéric Besson, Sébastien Ferré, Thomas Colcombet, Jean-Phillipe Pouzol, Yoann Padioleau, et Valérie Viet Triem Tong. J'ai particulièrement aimé cohabiter (pour reprendre le cri d'amour du crapaud, comme disait Desproges) avec mes voisins de bureaux successifs ; Julien, pour nos discussions enammées, surtout les fois où nous étions du même avis, et Thomas (G.) pour son éternelle bonne humeur. Les sportifs. Je ne saurais achever cette salve de remerciements sans rendre un hommage appuyé à la dream team du RUC Tennis : Patrice Burgevin, Ronan Fablet, Frédéric Guyomarch', Pierre Hellier, Guillaume Moreau, et leur entraîneur poète Maxime Dejoux, dit Maxou le fou. La pugnacité de Patrice n'aura malheureusement pas su à sauver l'équipe d'une relégation tant redoutée (par lui, essentiellement, en fait). Les conseillers. Durant ma vie d'étudiant puis de doctorant, trois personnes à la gentillesse sans borne m'ont prodigué leurs conseils éclairés. Yannick Letertre, que je suis venu solliciter à plusieurs reprises dès mon arrivée à la fac ; Didier Caucal, toujours disponible et attentif ; et Olivier Ridoux, dont les précieux conseils dans les moments délicats sont pour beaucoup dans l'aboutissement decetravail. Enn et surtout, je remercie Mireille, qui cumule quasiment tous les critères pour apparaître ici, puisqu'elle fut à la fois membre du jury, de l'insa, et du groupe Lande, ainsi qu'une relectrice méticuleuse, une collègue d'enseignement, une conseillère avisée, et une joueuse de Tennis émérite. Mais elle fut surtout une directrice de thèse disponible et exemplaire. Ses conseils abondants et divers qui m'ont toujours parus pertinents, soit immédiatement, soit dans un deuxième temps. Par le truchement d'un procédé (déposé) de sur-annotage polychrome de versions préliminaires d'articles, Mireille m'a appris la rigueur dans l'écriture et dans la démarche scientique. Sa franchise m'a également été très protable. Son sens de l'organisation restera pour moi un modèle du genre. Mireille m'a transmis un goût immodéré pour le travail planié, jalonné par des échéances raisonnables et respectées... Évidemment, j'entends d'ici les mauvaises langues persier. En avoir le goût n'est certes pas susants, aussi, je m'engage solennellement à y parvenir dans une prochaine vie. Je remercie par ailleurs les autorités concernés qui ont acceptées l'utilisation, dans ce document, de trois langues ; le français, l'anglais et le grecque (cf p. 114). La thèse est une épreuvequivaut la peine d'être vécue, ne serait-ce que par la richesse des rencontres qu'elle suscite. Dans des registres très diérents, Michel Van Den Bossche, Didier Caucal, Mireille Ducassé, Fergus Henderson, Daniel Herman, et Olivier Ridoux (entre autres!) resteront pour moi des modèles.

3 Avertissement Foreword L'introduction, les chapitres des parties I et IV, ainsi que les titres et les mini-tables des matières de tous les chapitres sont en français. Le corps de la partie technique de la thèse, à savoir le corps des chapitres des parties II et III, sont en anglais. The introduction, the whole chapters of part I and IV, as well as titles and minitables of contents of all chapters are written in French. The body of the technical part of the thesis, namely, the body of part II and III chapters, are written in English.

4

Table des matières 5 Table des matières 1 Introduction 11 1.1 L'analyse dynamique, un domaine de recherche délaissé.......... 12 1.2 Thèse et contributions............................ 13 1.3 Du choix de Mercury............................. 15 1.4 Débogage déclaratif et analyse de trace................... 16 1.5 Organisation du mémoire.......................... 17 I Contexte de l'étude 19 2 Extraction 21 2.1 Préambule sur les modèles d'exécution................... 22 2.2 Les sémantiques de langage de programmation.............. 22 2.3 Mise en uvre des modèles d'exécution................... 25 2.3.1 Instrumentation d'un interpréteur................. 26 2.3.2 Instrumentation du code source................... 28 2.3.3 Instrumentation du code intermédiaire............... 30 2.3.4 Instrumentation du code machine.................. 31 2.3.5 Utilisation des appels système.................... 32 2.3.6 Synthèse et discussion........................ 32 3 Analyse d'exécutions 35 3.1 Vues abstraites d'exécutions......................... 36 3.1.1 Trace chronologique......................... 36 3.1.2 Modèles basés sur des graphes ou des arbres............ 36 3.1.3 Prols d'exécutions.......................... 37 3.2 Mise en uvre automatisée de moniteurs.................. 38 3.2.1 Utilisation de deux processus en coroutine............. 38 3.2.2 Utilisation de processus légers.................... 40 3.2.3 Utilisation d'appels de procédures................. 41 3.2.4 Synthèse et discussion........................ 41

6 Table des matières II Mise en uvre automatisée d'analyseurs d'exécutions 43 4 Morphine, un système de débogage programmable pour Mercury 45 4.1 Mercury.................................... 46 4.2 Le système de trace de Mercury....................... 47 4.3 Les principaux concepts de Morphine.................... 51 4.4 Une session de mise au point avec Morphine................ 54 4.5 Construction de moniteurs d'exécutions.................. 59 4.6 Intégration de Morphine dans le système de trace............. 63 4.7 Performance de fget vis à vis de la construction de moniteurs...... 65 4.8 Discussion et conclusion........................... 66 5 Mise en uvre automatisée de moniteurs d'exécutions ecaces 69 5.1 Introduction.................................. 70 5.2 Un opérateur pour analyser les exécutions: foldt............. 70 5.2.1 Une dénition de foldt indépendante du langage......... 70 5.2.2 Une mise en uvre de foldt pour Mercury............ 72 5.2.3 L'interface utilisateur de foldt pour Mercury........... 73 5.3 Applications.................................. 77 5.3.1 Prols d'exécution.......................... 77 5.3.2 Abstractions graphiques....................... 80 5.3.3 Couverture de jeux de tests..................... 85 5.4 Experimentations............................... 89 5.4.1 Méthodologie............................. 89 5.4.2 Tables des résultats.......................... 91 5.4.3 Discussion............................... 93 5.5 Travaux connexes............................... 96 5.6 Conclusion................................... 98 III Spécications de modèles d'exécution 99 6 Spécications de modèles de traces de programmes logiques 101 6.1 Introduction.................................. 102 6.2 Une sémantique opérationelle pour Prolog................. 103 6.2.1 Description de la sémantique.................... 103 6.2.2 Exemples............................... 105 6.3 Une spécication formelle du modèle des boîtes de Byrd......... 106 6.3.1 Description de la spécication.................... 106 6.3.2 Prédicats tracés, prédicats opaques................. 107 6.3.3 Animation de la spécication par une transcription en λprolog. 107 6.4 Extensions du modèle des boîtes de Byrd................. 109 6.4.1 Un traitement spécial pour les prédicats déterministes...... 109 6.4.2 Un port unify............................ 110

Table des matières 7 6.4.3 Numéro de clauses aux ports unify................. 110 6.4.4 Profondeur d'exécution....................... 111 6.4.5 Numéro d'invocation de buts.................... 112 6.4.6 Numéro chronologique d'événements................ 112 6.4.7 Réunion des extensions........................ 113 6.5 Travaux connexes............................... 113 6.5.1 Utilisation de sémantiques opérationelles structurelles (SOS)... 113 6.5.2 Génération d'environnements de programmation......... 114 6.5.3 Autres systèmes de mise au point basés sur des sémantiques... 115 6.5.4 Comparaison avec notre travail................... 115 6.6 Conclusion................................... 116 IV Bilan et perspectives 117 7 Travaux en cours et perspectives 119 7.1 Validation formelle de traceurs....................... 120 7.2 Applications de l'opérateur foldt...................... 121 7.2.1 Détection d'invariants........................ 123 7.2.2 Prolage de valeurs.......................... 124 7.2.3 Évaluation de la qualité du code.................. 124 7.2.4 Tests.................................. 124 7.2.5 Débogage algorithmique....................... 125 7.3 Généralisation du noyau d'analyse dynamique............... 125 7.4 Connexion de foldt avec des outils de visualisation............ 126 7.5 Programmation par Contraintes....................... 126 8 Conclusion 127 8.1 Résumé des contributions.......................... 127 8.2 Vers un environnement d'analyse dynamique extensible et multi-langage 127 A Programmes Mercury 131 A.1 qsort.m.................................... 131 A.2 queens.m................................... 132 B Programmes λprolog 135 B.1 La sémantique de Nicholson et Foo en λprolog.............. 135 B.2 La spécication du modèle des boîtes de Byrd en λprolog........ 136 B.3 La spécication du modèle des boîtes de Byrd étendu avec des compteurs et le port unify................................ 138

8 Table des matières

Table des gures 9 Table des gures 2.1 Parallèle entre modèles d'exécution et modèles d'objets 3D....... 23 2.2 Récapitulatif de l'évaluation des diérents modes d'extraction...... 33 3.1 Récapitulatif de l'évaluation des diérents modes d'analyse d'exécution 42 4.1 Le prédicat append/3 en Mercury...................... 47 4.2 Un exemple d'événement de la trace de Mercury............. 50 4.3 Un exemple de trace exhaustive....................... 52 4.4 Illustration du mécanisme de ltrage d'événements de Morphine..... 54 4.5 Le résultat du programme mastermind erroné............... 55 4.6 Un résultat du prédicat display_mastermind/4.............. 56 4.7 Un moniteur qui compte le nombre d'appels................ 60 4.8 Un moniteur qui compte le nombre d'événements à chaque port..... 61 4.9 Un moniteur qui compte le nombre d'événements à chaque profondeur. 62 4.10 Un moniteur qui collecte l'ensemble des solutions d'un programme... 62 4.11 L'implémentation de la fonction trace() pour Morphine......... 64 4.12 Coût des moniteurs des gures 4.7 à 4.10.................. 66 5.1 Ce que l'utilisateur doit faire pour dénir un moniteur avec foldt... 73 5.2 Un moniteur qui compte le nombre d'appels................ 74 5.3 Invoquer le moniteur de la gure 5.2.................... 75 5.4 Les divers composants mis en jeux lorsque l'utilisateur invoque la commande : run_mercury(queens), foldt(count_call, Result)...... 75 5.5 Un moniteur qui compte la profondeur maximale d'une exécution par intervalle de 500 événements......................... 76 5.6 Un exemple de session utilisant le moniteur de la gure 5.5....... 77 5.7 Un moniteur qui compte le nombre d'événements à chaque port..... 78 5.8 Un moniteur qui compte le nombre d'événements à chaque profondeur. 79 5.9 Un moniteur qui collecte l'ensemble des solutions d'un programme... 80 5.10 Le graphe de ot de contrôle de l'exécution du programme des 5 reines. 81 5.11 Un moniteur qui calcule le graphe de ot de contrôle d'une exécution.. 81 5.12 Le graphe de ot de contrôle avec des compteurs de l'exécution des 5 reines 82 5.13 Le graphe d'appels dynamique de l'exécution du programme des 5 reines 83 5.14 Un moniteur qui calcule le graphe d'appels d'une exécution....... 84 5.15 L'arbre de preuves de l'exécution du programme des 5 reines....... 85

10 Table des gures 5.16 Un moniteur qui mesure le taux de couverture de prédicat des 5 reines. 87 5.17 Un moniteur qui mesure le taux de couverture de site des 5 reines.... 88 6.1 Une sémantique opérationnelle par continuation de Prolog........ 103 6.2 Les types des fonctions sémantiques de la gure 6.1........... 104 6.3 Une spécication formelle du modèle des boîtes de Byrd......... 106 6.4 Un programme Prolog (celui donné par Byrd pour illustrer son modèle de boîtes)................................... 109 6.5 La trace produite par le programme de la gure 6.4............ 109 6.6 Les types des fonctions sémantiques de la gure 6.3 étandues pour prendre en compte la profondeur........................... 111 6.7 Une spécication d'un modèle des boîtes de Byrd étendu......... 114 6.8 Résultat de la spécication de la gure 6.7 avec le programme de la gure 6.4 et la requête?- p.......................... 115 7.1 Une transformation de code source Prolog qui implémente une trace suivant le modèle des boîtes de Byrd...................... 120 7.2 Correction du traceur de la gure 7.1.................... 121 7.3 Les fonctions sémantiques de la gure 6.1 étendues pour prendre en compte les arguments............................. 122

11 Chapitre 1 Introduction Table des matières du chapitre 1 1.1 L'analyse dynamique, un domaine de recherche délaissé.. 12 1.2 Thèse et contributions...................... 13 1.3 Du choix de Mercury....................... 15 1.4 Débogage déclaratif et analyse de trace............ 16 1.5 Organisation du mémoire..................... 17 Du coût de production des diérentes phases du cycle de vie d'un logiciel. Des études telles que celle faite récemment par Hatton [Hatton 1997] montrent que la plus grande partie du coût de production d'un logiciel n'est pas engendrée lors de la phase de développement, mais lors de la phase de maintenance. Hatton indique que 20 % du coût de développement est généré lors de la phase de développement, 40 % lors de la phase de correction des bogues, et 40 % lors de la phase d'ajout de nouvelles fonctionnalités. C'est donc bien lors de la phase de correction-maintenance qu'il y a le plus d'opportunités d'obtenir des gains de productivité importants. Les analyses de programmes sont des outils très utiles pour réduire les coûts de production, à chacune de ces diérentes étapes. Analyse de programme ; analyses statiques, analyses dynamiques. Les analyses de programme inférent et vérient des propriétés sur le programme. Elles fournissent une grande aide au programmeur à chaque étape du développement d'un logiciel. Elles sont utiles lors de la phase de développement initial pour assurer les propriétés spéciées dans le cahier des charges ; lors de la phase de maintenance pour comprendre le fonctionnement et les éventuels dysfonctionnements du programme ; et lors de la phase d'ajout de nouvelles fonctionnalités pour s'assurer que les modications ne viennent pas invalider les propriétés du programme. Une analyse de programme est dite statique si elle ne prend en entrée que le code source du programme. Elle est dite dynamique si les propriétés sont inférées ou vériées par l'observation de l'exécution du programme.

12 Introduction De l'intérêt des analyses dynamiques par rapport aux analyses statiques. Permettant d'exhiber des propriétés moins générales que les analyses statiques car dépendantes des données d'entrées, les analyses dynamiques se révèlent néanmoins très utiles en pratique. Tout d'abord parce que certaines propriétés de programme sont indécidables. Par exemple, vérier qu'une fonction qui calcule la solution d'une équation polynomiale à coecients dans les entiers produit un entier naturel (dixième problème de Hilbert) est indécidable. Certes, il est possible de vérier certaines propriétés indécidables en restreignant le pouvoir d'expression des langages par l'intermédiaire d'un système de type [Milner 1978]. Mais toutes les propriétés de programmes ne peuvent pas être vériées ainsi sans restreindre de façon exagérée le pouvoir d'expression du langage. Tout l'enjeu de la recherche sur les langages de programmation consiste à trouver un ensemble de restrictions qui permettent de garantir le plus grand nombre de propriétés possible, sans trop diminuer le pouvoir d'expression du langage. Les analyses dynamiques sont très utiles lorsque que l'on est confronté à des propriétés pour lesquelles il n'existe pas un compromis satisfaisant. Par ailleur, quand l'utilisateur cherche à comprendre le fonctionnement ou les dysfonctionnements d'un programme, les analyses dynamiques permettent d'obtenir des informations beaucoup plus précises que les analyses statiques. Des systèmes d'analyses dynamiques tels que les débogueurs, les moniteurs et les proleurs sont donc bien nécessaires, notamment lors de la phase la plus coûteuse du cycle de production d'un logiciel ; la phase de maintenance. Dénition 1 (débogueur, moniteur, proleur) Un analyseur dynamique est un système qui génère des informations relatives à l'exécution des programmes. Un débogueur est un système d'analyse dynamique qui opère de façon interactive, c'est-à-dire, qui permet à l'utilisateur de spécier à la volée, les informations et les propriétés qu'il désire avoir sur l'exécution en cours. Un moniteur d'exécutions est un système d'analyse dynamique non interactif. Un proleur est un moniteur qui donne des informations relatives au temps d'exécution des diérents composants du programme. Les moniteurs extraient et vérient des propriétés globales, relatives à l'ensemble de l'exécution, alors que les débogueurs font la même chose pour vérier des propriétés plus locales. Mais tous ont la même nalité : extraire ou vérier des propriétés relatives aux exécutions. Pour autant, les débogueurs et les moniteurs sont souvent implémentés séparément. L'une des idées défendue dans notre thèse est qu'en faisant partager la même architecture aux diérents analyseurs dynamiques, on permet à ces outils de s'enrichir mutuellement. 1.1 L'analyse dynamique, un domaine de recherche délaissé Malgré les coûts très importants générés lors de la phase de maintenance, peu d'efforts en terme de recherche ont porté sur les environnements de programmation en général, et sur l'analyse dynamique en particulier [van Emden 1993, Wadler 1998]. Selon Wadler [Wadler 1998], le manque d'intérêt porté aux environnements de programmation

Thèse et contributions 13 est l'une des principales raisons expliquant le peu d'impact de la recherche sur les langages de programmation dans le monde industriel. Le manque d'intérêt porté à l'analyse dynamique est dû au fait que ces outils sont extrêmement coûteux à mettre en uvre, rendant ainsi une telle recherche dicilement valorisable dans un contexte académique. Les raisons expliquant le coût induit par la mise en uvre d'outils d'analyse dynamique sont les suivantes. Des systèmes techniques à mettre en uvre. Les analyseurs dynamiques sont des programmes techniques à mettre en uvre. Pour les implanter, il est typiquement nécessaire de modier le système d'exécution, que généralement seule une poignée de personnes maîtrise parfaitement. Pas de maîtrise sur le système sous-jacent. Le fait de reposer sur un système complexe (un compilateur), bien souvent développé par des tiers, ne pose pas uniquement des problèmes en termes de développement initial, mais aussi en termes de maintenance. Des outils diciles à réutiliser. Les outils ainsi développés sont vite périmés. En eet, étant généralement intégrés au compilateur, il est dicile de réutiliser de tels outils pour d'autres systèmes, dans d'autres contextes. Des besoins versatiles. Il est extrêmement dicile de connaître les besoins en outils d'analyse de programmes, car ils varient d'un utilisateur à l'autre. En eet, la compréhension de l'exécution d'un programme pour la personne chargée de maintenir un code varie en fonction de sa compétence, de son expérience du système de programmation utilisé, ainsi que de sa connaissance du code à maintenir [Ducassé & Emde 1988]. Il est dicile de connaître a priori les besoins de ces diérents utilisateurs dans ces diérents cas de gure. Il est donc souhaitable que chaque utilisateur, quel que soit son niveau de compétence sur le code à maintenir, puisse spécier facilement les analyses dynamiques qui lui permettent de comprendre le comportement de l'exécution des programmes. 1.2 Thèse et contributions Dans cette thèse, nous proposons une architecture qui vise à faciliter la construction d'analyseurs dynamiques performants. Ces analyseurs ont des performances du même ordre de grandeur que leurs équivalents, implémentés à la main, par modication du système de compilation. Ils peuvent être mis en uvre par des utilisateurs sans connaissance particulière du système de compilation, que, de plus, ils n'ont pas besoin de modier. Ceci permet aux utilisateurs d'implémenter les outils dont ils ont besoin. Cette architecture est basée sur : 1. Une instrumentation systématique du programme exécuté qui produit une image très détaillée de l'exécution : la trace.

14 Introduction 2. Un ensemble de primitives qui permettent d'analyser cette trace ecacement (à la volée). Dénition 2 (trace d'exécution) Une trace d'exécution est un ensemble d'informations produites par l'exécution d'un programme. D'une certaine manière, le résultat d'un programme peut être vu comme une trace, très grossière, de son exécution. Pour comprendre la façon dont un programme a calculé son résultat, on procède à une instrumentation qui rajoute des eets de bords, fournissant ainsi de l'information supplémentaire sur les états intermédiaires de l'exécution. Cette information est analysée et abstraite avant d'être présentée aux utilisateurs. Ainsi, pour la construction de tout analyseur dynamique, nous distinguons les étapes suivantes ([Ducassé & Noyé 1994]): 1. Dénition d'un modèle de l'exécution (ou modèle de trace). 2. Extraction de l'information correspondant à ce modèle. 3. Analyse/abstraction de l'information extraite. 4. Visualisation du résultat de l'analyse. Dans cette thèse, nous nous concentrons uniquement sur les trois premières étapes. Souvent, ces quatre étapes ne sont pas considérées explicitement, ni séparément. Par exemple, l'extraction de l'information et son analyse sont faites en même temps. Notre architecture repose sur une séparation explicite entre le système d'exécution et le système d'analyse d'une part, ainsi qu'entre les diérentes phases de la construction de l'analyseur d'autre part. La structure modulaire de cette architecture devrait faciliter la réutilisation des analyseurs pour d'autres systèmes d'exécution. Cette approche est largement inspirée d'opium [Ducassé 1999c], un débogueur extensible pour Prolog. Nous avons étendu les primitives d'opium dans le cadre de la construction de moniteurs d'exécutions. Cette étude a été menée dans le cadre du langage de programmation logique et fonctionnel Mercury [Somogyi et al. 1996]. Cependant, les concepts utilisés sont indépendants du paradigme de programmation. La trace sur laquelle nous basons la construction de nos analyseurs (étape 1) se doit de reéter le plus dèlement possible la sémantique opérationnelle du langage. C'est pourquoi nous proposons également un cadre de modélisation des traces d'exécutions basé sur une sémantique opérationnelle du langage. Cette spécication formelle de la trace nous permet de valider expérimentalement les traceurs et de prouver leur correction. Cette étude a été menée dans le cadre de Prolog standard [Deransart et al. 1996]. Contributions. Les contributions de notre travail sont les suivantes : Opium [Ducassé 1999c], un débogueur extensible de programmes Prolog, a été adapté pour le langage Mercury [Somogyi et al. 1996]. Ce travail a été réalisé en collaboration avec les chercheurs du projet Mercury de l'université de Melbourne, dans le cadre du projet ARGo, un projet de recherche et développement Européen Esprit.

Du choix de Mercury 15 Nous avons étendu les primitives d'opium pour permettre la construction de moniteurs d'exécutions ecaces. Le système d'analyse d'exécutions résultant, Morphine, est disponible 1 sous licence GNU/GPL, et est distribué avec Mercury 2. Morphine a également été déposé à l'agence de protection des programmes (APP). Nous avons montré comment Morphine pouvait être utilisé pour implémenter une large palette de moniteurs d'exécutions. Nous avons initié une réexion jetant les bases d'une notion de couverture de jeux de tests dans le cadre de la programmation logique. Nous avons proposé une spécication formelle du modèle de Byrd, ainsi qu'une extension de ce modèle. Ce travail fournit un cadre pour la validation expérimentale et formelle de la correction des traceurs pour Prolog. 1.3 Du choix de Mercury Actuellement, des langages impératifs tels que Fortran, C, C++ ou Java, ont plus d'impact que les langages de programmation logique ou fonctionnelle sur l'industrie du logiciel. Nous tenons donc à justier dès maintenant notre choix d'avoir utilisé Mercury pour illustrer notre thèse. Tout d'abord, beaucoup des concepts utilisés dans cette thèse sont indépendants du paradigme de programmation, comme le démontre une étude allant dans le même sens fait pour le langage C [Ducassé 1999b]. De plus, Mercury nous paraît être un langage plus proche de ce que seront les langages des années futures. Nous voyons deux raisons qui permettent de penser cela. La première raison est que Mercury est un langage permettant au compilateur de faire un grand nombre d'optimisations. Dans un premier temps, et dans une certaine mesure, l'utilisateur écrit son programme sans avoir à se soucier de performance ; le compilateur s'occupe tout seul d'optimiser les programmes. C'est en ce sens que Mercury est placé dans la catégorie des langages dits déclaratifs. De ce point de vue, Mercury est bien plus déclaratif que Prolog par exemple. Pour un grand nombre d'applications, Mercury produit du code dont les performances sont équivalentes à celui provenant d'un programme écrit en C. La deuxième raison est que Mercury est un langage qui permet au compilateur de faire une pléthore d'analyses statiques qui détectent un grand nombre d'erreurs dès la compilation. Ceci permet de réduire considérablement le coût associé à toute les phases de développement. Enn, notre point de vue est de considérer que, quand cela est possible, il est préférable d'essayer de détecter les erreurs en utilisant d'abord une analyse statique, et de n'observer l'exécution des programmes uniquement quand on ne peux plus faire autrement. En eet, il est important en termes de coût de développement de détecter les erreurs le plus tôt possible. De plus, la localisation peut parfois être 1. www.irisa.fr/lande/jahier/morphine.html 2. www.cs.mu.oz/research/mercury/

16 Introduction très précise avec ce type d'analyse. Les analyses statiques ne permettent pas de détecter toutes les erreurs, ni d'optimiser toutes les sources d'inecacité. Il reste donc un grand champ d'applications pour les analyses dynamiques. Développer des outils d'analyse dynamique dans le contexte d'un langage qui eectue un grand nombre d'analyses statiques nous oblige à nous intéresser aux vrais problèmes : ceux qu'aucune analyse statique ne peut résoudre. En d'autres termes, toutes les erreurs syntaxiques et autres étourderies ayant été capturées très tôt par le compilateur, il ne reste que les erreurs logiques, structurelles, qui demandent une compréhension profonde du fonctionnement du programme. Des outils exibles et extensibles sont alors d'autant plus nécessaires. 1.4 Débogage déclaratif et analyse de trace Il est parfois armé que pour mettre au point des programmes, et notamment ceux écrits dans des langages déclaratifs, il est préférable d'utiliser une approche déclarative. On parle à ce propos de débogage déclaratif ou débogage algorithmique, dont Shapiro a été le précurseur [Shapiro 1983]. La philosophie du débogage algorithmique est la suivante : un langage déclaratif décharge l'utilisateur des préoccupations (bassement) opérationnelles. L'utilisateur a simplement à s'intéresser au quoi, laissant le soin au système d'exécution, compilateur ou interpréteur, de gérer le comment. Lors de la phase de mise au point, comme lors de la phase de développement, l'utilisateur doit donc simplement s'occuper de vérier que la sémantique déclarative de son programme est cohérente et conforme à son cahier des charges. En outre, les sémantiques opérationnelles des langages déclaratifs sont généralement complexes. Présenter une image opérationnelle à l'utilisateur n'est donc pas nécessairement pertinent. Mercury, le langage que nous utilisons pour illustrer nos propos, est l'un de ces langages dits déclaratifs ; les déclarations de types, de modes et de déterminismes permettent au compilateur de faire un grand nombre de vérications statiques et d'optimisations. L'utilisateur a donc peu à s'occuper de performance lors du développement du programme ; c'est le compilateur qui eectue ce travail. Pour autant, nous estimons qu'il est faux de penser que le programmeur n'a jamais à se soucier de la façon dont le programme s'exécute. En eet, les optimisations faites par les compilateurs modernes sont très utiles, mais elles ne concernent somme toute que certaines optimisations simples. Lorsque l'algorithmique d'un programme est en n 3, il est bien rare que le compilateur puisse la transformer en un programme en n 2. Ainsi, quand le programme donne le bon résultat, mais dans un intervalle de temps anormalement grand, il s'agit d'être capable de comprendre quelles parties du programme sont sources d'inecacité. De plus, à partir d'une trace reétant la sémantique opérationnelle, il est toujours possible, et souhaitable, de reconstruire une vue de plus haut niveau ; il est même possible d'en construire plusieurs, comme nous le montrons dans la suite (voir notamment la section 5.3.2 où nous montrons comment reconstruire un arbre de preuves à par-

Organisation du mémoire 17 tir de la trace). Mallet et Ducassé [Mallet & Ducassé 1999] le font également dans le cadre des bases de données déductives. Ainsi, à partir d'un modèle opérationnel très détaillé de l'exécution, nous pouvons construire à la fois des outils ayant une connotation opérationnelle, et des outils présentant une image déclarative de l'exécution. 1.5 Organisation du mémoire Première partie Contexte de l'étude et état de l'art. Cette partie introduit les concepts du domaine et étudie les travaux antérieurs relatifs à la construction automatisée d'analyseurs dynamiques ainsi qu'à leur dénition formelle. Deuxième partie Construction automatisée de moniteurs d'exécutions. Nous présentons une architecture qui permet de faciliter la construction d'analyseurs dynamiques dans le cadre du compilateur Mercury. Nous montrons également comment utiliser cette architecture pour implémenter une grande variété d'analyseurs dynamiques ; proleurs d'exécutions, couverture de jeux de tests, abstractions basées sur des graphes. Les mesures que nous avons eectuées révèlent que les analyseurs résultants ont des performances du même ordre de grandeur que des analyseurs implémentés à la main par modication du système de compilation. Troisième partie Spécication de modèles d'exécutions. Nous proposons dans cette partie un cadre de spécication des modèles de trace d'exécutions de programmes Prolog basé sur une sémantique opérationnelle. Ces spécications formelles de la trace nous permettent de valider expérimentalement les traceurs et de prouver leur correction. Quatrième partie Conclusion et perspectives. Nous décrivons enn des travaux en cours et nous donnons un certain nombre de pistes de recherche à court, moyen et long terme. Schéma de lecture Chacune des parties de ce document devrait pouvoir être lue indépendamment des autres. Cependant, pour les personnes peu ou pas familières avec la problématique de l'analyse dynamique, il est tout de même recommandé de lire auparavant la première partie. Chacune des parties est découpée en chapitres. Pour la partie II, il est conseillé de lire les chapitres dans l'ordre. Les langages de programmation utilisés pour l'illustration de notre thèse sont Mercury dans la deuxième partie et Prolog dans la troisième. Aucune connaissance a priori de ces langages ne devrait être nécessaire pour suivre le l du discours.

18 Introduction

19 Première Partie Contexte de l'étude Dans cette partie, nous présentons un certain nombre de travaux antérieurs relatifs à la mise en uvre automatisée d'analyseurs dynamiques. Toute analyse dynamique se décompose en une phase d'extraction de l'information, et en une phase d'analyse de cette information. Nous étudions au chapitre 2 la première phase, et la deuxième au chapitre 3.

21 Chapitre 2 Extraction Table des matières du chapitre 2 2.1 Préambule sur les modèles d'exécution............ 22 2.2 Les sémantiques de langage de programmation....... 22 2.3 Mise en uvre des modèles d'exécution............ 25 2.3.1 Instrumentation d'un interpréteur............... 26 2.3.2 Instrumentation du code source................. 28 2.3.3 Instrumentation du code intermédiaire............. 30 2.3.4 Instrumentation du code machine................ 31 2.3.5 Utilisation des appels système.................. 32 2.3.6 Synthèse et discussion...................... 32 Pour pouvoir analyser les exécutions, la première étape consiste à extraire un certain nombre d'informations à certains points de programme. En quelque sorte, on discrétise l'exécution en l'observant à des points de programmes particuliers. Cette démarche est comparable à celle qui consiste à discrétiser un objet dans l'espace dont la forme est trop complexe pour être décrit de façon exhaustive. Nous détaillons en section 2.1 ce parallèle avec la modélisation d'objet dans l'espace pour donner une intuition sur la notion de modèle d'exécution. Par ailleurs, les sémantiques de langages, et notamment les sémantiques dites opérationnelles, sont des spécications formelles de la façon dont s'exécutent les programmes. Ce sont donc des outils privilégiés pour la description formelle des modèles d'exécution. La section 2.2 est ainsi consacrée à la description des diérents types de sémantiques. Pour mettre en uvre ces modèles d'exécution, c'est-à-dire pour en extraire de l'information à chacun des points de programme spéciés par le modèle, il existe plusieurs méthodes. Nous passons en revue en section 2.3 ces diérentes méthodes.

22 Extraction 2.1 Préambule sur les modèles d'exécution Que ce soit, par exemple, en mécanique, ou bien en imagerie numérique, pour pouvoir manipuler des objets en trois dimensions, pour raisonner, ou pour faire des simulations, il est nécessaire d'en avoir une description mathématique. La plupart du temps, ces objets ont une forme trop complexe pour être modélisés par des fonctions. On eectue donc une discrétisation qui permet d'obtenir une représentation de l'objet, certes imparfaite, mais nie. Pour eectuer un telle discrétisation, on doit : 1. choisir un pas de discrétisation ; par exemple, 1 mm, 2. dénir un certain nombre d'informations disponibles à chaque point du modèle ; par exemple la couleur, la température, la texture, la luminosité. Cette modélisation, bien que ne décrivant pas de façon exhaustive l'ensemble des caractéristiques d'un objet, n'en reste pas moins utile pour en déduire des propriétés. La nature de ces propriétés va dépendre du grain de la modélisation et du type d'informations disponibles à chaque point du modèle. Par exemple, pour calculer la résistance aux chocs de l'objet, on aura besoin d'un coecient d'élasticité ; pour le visualiser, on aura besoin de sa couleur et de sa texture. De la même façon, pour dénir un modèle d'exécution, nous allons faire une discrétisation de l'exécution en choisissant pour cela : 1. Des points de programmes que nous appelons événements d'exécution ;cepeuvent être, par exemple, les appels et les sorties des fonctions du programme ou de boucles. 2. Pour chaque événement, un certain nombre d'informations relatives à l'état courant de l'exécution. Nous appelons ces informations des attributs de l'événement ; ce peuvent être, par exemple, le nom de la procédure courante, la profondeur de l'exécution, l'instanciation courante des variables sous portée, ou bien la pile d'appels. Nous résumons dans le tableau 2.1 notre parallèle entre modélisation d'objets en trois dimensions et modélisation d'exécutions de programmes. À chaque fois, le type de propriétés de programmes que l'on va être capable de calculer va dépendre de la discrétisation eectuée. En outre, une discrétisation très ne doit permettre d'obtenir une meilleure précision au prix de temps de calculs plus longs. En d'autres termes, il n'y a pas de meilleure discrétisation ; il y a juste des discrétisations adaptées à des analyses particulières. Le choix d'une bonne discrétisation pour une propriété donnée est délicat. Pour cette raison, le choix du modèle doit pouvoir être souple. 2.2 Les sémantiques de langage de programmation Les sémantiques sont des outils très puissants pour dénir les langages et leurs modes d'exécutions. Les sémantiques [Mitchell 1996, Nielson & Nielson 1992] sont dé- nies par des fonctions qui prennent en argument des expressions du programme. Une

Les sémantiques de langage de programmation 23 Exécutions Objets 3D Modèle ensemble d'événements ensemble de points Points du modèle événement = tuple d'attributs nom de la procédure, arguments, profondeur,... points = tuple d'informations position dans l'espace, couleur, température, texture,... Choix d'un pas points de programme distance entre les points Index l'ordre chronologique des position des points dans Représentations abstraites du modèle événements trace chronologique, graphes de ot de contrôle, graphes d'appels,... l'espace représentation en 2D ou 3D, en couleur ou en niveau de gris, la couleur donnée en fonction de la position ou de la température,... Figure 2.1 Parallèle entre modèles d'exécution et modèles d'objets 3D propriété importante que l'on cherche à obtenir lorsque l'on dénit une sémantique est la compositionnalité. Dénition 3 (Sémantiques compositionnelles) Une sémantique est dite compositionnelle si la sémantique de toute expression est construite strictement à partir de celle de ses sous-expressions. La propriété de compositionnalité d'une sémantique est fondamentale d'un point de vue pratique. Elle permet d'assurer que la sémantique dénit une relation de congruence entre les éléments de son co-domaine, ce qui permet de faire des preuves locales, donc plus simples à mettre en uvre ; ces preuves sont eectuées par cas sur la structure syntaxique des programmes (induction structurelle). Dénition 4 (Sémantiques déclaratives et sémantiques opérationnelles) Une sémantique est dite déclarative ou intentionnelle si elle décrit le résultat d'une expression à partir de ses arguments d'entrée, sans décrire comment ce résultat est obtenu. Une sémantique est dite opérationnelle ou extensionnelle si, au contraire, elle décrit la façon dont le résultat de l'expression est obtenu. D'un certain point de vue, les sémantiques déclaratives ont un grain moins n que les sémantiques opérationnelles. Quand on dénit une sémantique opérationnelle et une sémantique déclarative, il est de bon ton de vérier qu'elles conduisent au même résultat. Un style de sémantique souvent employé est celui des sémantiques dites axiomatiques. Dénition 5 (Sémantiques axiomatiques) Une sémantique est dite axiomatique si elle est dénie indirectement par des axiomes et des règles spéciant des propriétés du

24 Extraction langage. Ces axiomes permettent, entre autre, de déduire le résultat d'un programme. Certains aspects de l'exécution peuvent être ignorés cependant. Les sémantiques axiomatiques sont généralement intentionnelles. Le fait d'être énoncé sous formes d'axiomes relatifs aux propriétés du programmes rend ce type de sémantiques particulièrement adapté aux preuves de corrections de programmes. Ces preuves sont d'autant plus facilitées que ces sémantiques opèrent généralement sur des ensembles récursivement énumérables [Mitchell 1996]. Quand on parle de preuves de programme, on désigne par défaut des preuves de correction partielle ; c'est-à-dire, des preuves de propriétés valables sous l'hypothèse que les programmes terminent. Quand on prend aussi en compte la terminaison, on parle alors de correction totale. Les dénitions précédentes caractérisent la nature des sémantiques. Celles qui suivent sont relatives au style de formalisme utilisé pour dénir les sémantiques. Dénition 6 (Sémantiques par continuations et sémantiques en style direct) Une sémantique par continuations est une sémantique qui prend en argument des continuations, c'est-à-dire, des fonctions qui représentent le sens du reste du programme. Une sémantique en style direct est une sémantique qui n'utilise pas de continuation dans sa dénition. Les continuations ont été inventés par Strachey [Strachey & Wadsworth 2000] 1 pour décrire de façon élégante les sauts (goto). En particulier, les continuations permettent de décrire, de façon concise et élégante, le retour arrière (backtracking) en Prolog, ou les exceptions [de Bruin 1986]. Elles permettent en fait de décrire facilement tout ce qui peut être implanter par des piles. Les piles étant une structure de données utilisées dans tous les compilateurs, il n'est guère surprenant que les continuations soient un formalisme particuliérement adaptées pour décrire les sémantiques, et notamment les sémantiques opérationnelles. Dénition 7 (Sémantiques dénotationnelles) Une sémantique est dite dénotationnelle si elle associe à chaque expression du langage une valeur (sa dénotation) dans un ensemble (partiellement) ordonné et complet 2 et qu'elle manipule des objets innis (fonctions, structures de données innies) comme des objets de première classe, en s'appuyant sur la continuité des opérations et sur le concept de point xe dans un CPO. Les sémantiques dénotationnelles s'opposent souvent aux sémantiques opérationnelles telles que les sémantiques dites structurelles [Plotkin 1981] (SOS) ou les sémantiques naturelles [Kahn 1987]. Ces sémantiques sont données en termes de systèmes de transitions, où chaque transition décrit une étape de calcul. Les sémantiques qui sont à la 1. La date de parution peut surprendre les lecteurs attentifs, Strachey étant mort en 1973. Il s'agit en fait d'une réédition, plus accessible que l'article original, parue dans un numéro spécial dédié à Strachey. 2. Un ensemble ordonné est complet lorsque toute suite croissante admet une borne supérieure (complete partial order, ou CPO en anglais).

Mise en uvre des modèles d'exécution 25 fois opérationnelles, dénotationnelles et compositionnelles sont dites complètement abstraites (fully abstract semantics). Ces sémantiques sont évidemment très attrayantes car elles permettent de faire des preuves relatives à l'exécution des programmes (car opérationnelles) qui soient locales (car compositionnelles). Nous utilisons d'ailleurs en section 6.2 une sémantique de programmes logiques Prolog [Nicholson & Foo 1989, de Bruin & de Vink 1989] qui est à la fois dénotationnelle, opérationnelle, et par continuation ; dans cette sémantique, les continuations se révèlent particulièrement adaptées pour décrire le comportement de la coupure (`!'). En eet, l'implémentation des coupures est liée à l'utilisation d'une pile : une coupure enlève de la pile de recherche les points de choix de la procédure courante. Discussion à propos de ces dénitions. Pour Nielsson et Nielsson, une sémantique dénotationnelle est nécessairement intentionnelle [Nielson & Nielson 1992]. Il ne nous paraît pas judicieux de restreindre l'utilisation de ces sémantiques à des descriptions purement intentionnelles de l'évaluation d'une expression. La preuve en est qu'il existe des sémantiques qui sont à la fois dénotationnelles et opérationnelle : les sémantiques complètement abstraites. De façon similaire, on trouve parfois dans la littérature que les sémantiques dénotationnelles sont nécessairement compositionnelles [Mitchell 1996, Nielson & Nielson 1992]. Or, la notion de compositionnalité ne dépend pas du style (dénotationnel ou pas) de formalisme utilisé pour décrire une sémantique. Janssen [Janssen 1996] (dans un contexte diérent, mais très proche, de celui du traitement automatique des langues naturelles) va même jusqu'a dire que ce qui n'est pas compositionnel est trop peu ou mal formalisé. Les raisons pour lesquelles les sémantiques dénotationnelles devraient être compositionnelles, et pas les sémantiques opérationelles, sont d'ordre historique. En effet, la plupart des sémantiques qui décrivent le mode d'exécutions des programmes (SOS) ne sont pas compositionnelles, alors que les sémantiques purement intentionnelles données dans un style dénotationnel le sont. La sémantique de Nicholson et Foo [Nicholson & Foo 1989], qui décrit dans un style dénotationnel le mode d'exécution des programmes Prolog, montre bien que cette généralisation (dénotationnel = compositionnel) est malencontrueuse. Un autre example est la sémantique introduite par Le Charlier et al. [Charlier et al. 2001], qui, à l'inverse, est une sémantique compositionnelle donnée sous la forme d'un système de transitions (comme les SOS). La compositionnalité d'une sémantique ne dépend donc bien pas du style employé pour la dénir. 2.3 Mise en uvre des modèles d'exécution Il existe plusieurs façons de mettre en uvre des modèles d'exécution, c'est-à-dire, d'extraire de l'information d'une exécution [Ducassé & Noyé 1994]. On peut instrumenter un interpréteur, le code source, le code intermédiaire, le code objet, le code exécutable, ou bien récupérer des appels systèmes. La plupart des travaux que nous référençons traitent, de façon plus ou moins dissociée, à la fois des phases d'extraction

26 Extraction et d'analyse. Nous nous focalisons ici sur la phase d'extraction ; la phase d'analyse est abordée au chapitre suivant. Chaque mode d'extraction est décrit et évalué en fonction des six critères suivants. Un récapitulatif de ces évaluations est donné en gure 2.2 en n de chapitre. 1. Pertinence de la trace générée vis à vis de la sémantique du langage. 2. Indépendance vis à vis du langage à analyser. 3. Indépendance vis à vis de l'architecture sous-jacente (système d'exploitation et type de machine). 4. Facilité de mise en uvre et de maintenance. 5. Performance du programme exécuté sous le contrôle du traceur. 6. Le compilateur et l'analyseur sont deux systèmes distincts. Le sixième critère mérite sans doute une justication. Nous pensons en eet que, à l'instar de Brooks et al. [Brooks et al. 1992], lorqu'il existe un compilateur, le système d'analyse dynamique et le compilateur ne doivent pas former deux systèmes distincts. En eet, certaines erreurs ne se manifestent qu'en présence des optimisations. Certains programmes ne sont exécutables que dans leur version optimisée à cause de contraintes de taille mémoire ou de temps d'exécution. Quand on cherche les goulots d'étranglement dans un programme, c'est vraiment le programme optimisé que l'on veut observer. On est obligé de recompiler les programmes pour les analyser. Parfois, les erreurs proviennent de bogues dans les optimisations elles-mêmes. Même s'il est vrai qu'il est souvent bon que certains détails de l'exécution soient cachés à l'utilisateur, nous pensons qu'il est préférable, dans ce cas, de laisser le soin à l'analyseur de cacher certains détails. Un certain nombre de travaux prometteurs ontété eectués [Adl-Tabatabai & Gross 1993, Adl-Tabatabai & Gross 1996, Brooks et al. 1992, Coutant et al. 1988, Copperman 1994, Tice & Graham 1998, Wismüller 1994] qui visent à rendre transparentes à l'utilisateur les optimisations faites par le compilateur. 2.3.1 Instrumentation d'un interpréteur Une première méthode pour extraire des informations relatives à l'exécution de programmes consiste à instrumenter un interpréteur. Cette approche est attrayante, car les modèles d'exécution des langages de programmation sont parfois décrits sous forme de sémantiques formelles. De telles sémantiques peuvent aisément être traduites dans un langage de programmation, conduisant ainsi à des interpréteurs [Consel & Khoo 1991]. Ces sémantiques peuvent également être modiées pour dénir des analyseurs d'exécutions qui peuvent, à leur tour, être exécutés ; on obtient ainsi des systèmes d'analyses d'exécutions dénis formellement. Il existe une vaste littérature basant la construction d'analyseur sur des interpréteurs. Nous nous contentons ici de décrire quelques travaux parmis les plus pertinents compte tenu de ce que nous faisons dans la suite.