Analyse Statique de Programmes



Documents pareils
Analyse de sécurité de logiciels système par typage statique

Bases de programmation. Cours 5. Structurer les données


INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

Chapitre VI- La validation de la composition.

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

Suivant les langages de programmation, modules plus avancés : modules imbriqués modules paramétrés par des modules (foncteurs)

Classes et Objets en Ocaml.

Algorithmique et Programmation, IMA

UE C avancé cours 1: introduction et révisions

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

Exclusion Mutuelle. Arnaud Labourel Courriel : arnaud.labourel@lif.univ-mrs.fr. Université de Provence. 9 février 2011

IN Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C

Java 1.5 : principales nouveautés

Cours intensif Java. 1er cours: de C à Java. Enrica DUCHI LIAFA, Paris 7. Septembre Enrica.Duchi@liafa.jussieu.fr

Introduction au langage C

Vérification formelle de la plate-forme Java Card

LMI 2. Programmation Orientée Objet POO - Cours 9. Said Jabbour. jabbour@cril.univ-artois.fr

Génie Logiciel avec Ada. 4 février 2013

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

Utilisation des tableaux sémantiques dans les logiques de description

UE Programmation Impérative Licence 2ème Année

DE L ALGORITHME AU PROGRAMME INTRO AU LANGAGE C 51

Prénom : Matricule : Sigle et titre du cours Groupe Trimestre INF1101 Algorithmes et structures de données Tous H2004. Loc Jeudi 29/4/2004

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3.

ALGORITHMIQUE ET PROGRAMMATION En C

Table des matières PRESENTATION DU LANGAGE DS2 ET DE SES APPLICATIONS. Introduction

Informatique Générale

Programmer en JAVA. par Tama

Cours de Programmation 2

Recherche dans un tableau

TP3 : Manipulation et implantation de systèmes de fichiers 1

Programmation en Java IUT GEII (MC-II1) 1

V- Manipulations de nombres en binaire

Quatrième partie IV. Test. Test 15 février / 71

Machines virtuelles Cours 1 : Introduction

Les structures de données. Rajae El Ouazzani

as Architecture des Systèmes d Information

SSTIC Désobfuscation automatique de binaires. Alexandre Gazet. Yoann Guillot. Et autres idyles bucoliques...

length : A N add : Z Z Z (n 1, n 2 ) n 1 + n 2

Cours de Master Recherche

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

Cours d initiation à la programmation en C++ Johann Cuenin

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

Projet d informatique M1BI : Compression et décompression de texte. 1 Généralités sur la compression/décompression de texte

Génie Logiciel I. Cours VI - Typage statique / dynamique, fonctions virtuelles et classes abstraites, flots d entrées / sorties, et string

Plan du cours Cours théoriques. 29 septembre 2014

Introduction à la programmation orientée objet, illustrée par le langage C++ Patrick Cégielski

Introduction à la Programmation Parallèle: MPI

Claude Delannoy. 3 e édition C++

Gestion mémoire et Représentation intermédiaire

Théorie de la Programmation

Calculabilité Cours 3 : Problèmes non-calculables.

Cours 1 : La compilation

Cours d Algorithmique et de Langage C v 3.0

Héritage presque multiple en Java (1/2)

EPREUVE OPTIONNELLE d INFORMATIQUE CORRIGE

Centre CPGE TSI - Safi 2010/2011. Algorithmique et programmation :

Principes des langages de programmation INF 321. Eric Goubault

Auto-évaluation Programmation en Java

modules & compilation

Machines virtuelles fonctionnelles (suite) Compilation ML Java

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

Encapsulation. L'encapsulation consiste à rendre les membres d'un objet plus ou moins visibles pour les autres objets.

Université de Bangui. Modélisons en UML

Les processus légers : threads. Système L3, /31

Programmation Objet Java Correction

Algorithmique et Programmation Fonctionnelle

Composants génériques de calcul scientifique

Cours de Programmation Impérative: Zones de mémoires et pointeurs

Notes du cours 4M056 Programmation en C et C++ Vincent Lemaire et Damien Simon

Correction du baccalauréat ES/L Métropole 20 juin 2014

TP, première séquence d exercices.

Cours de C++ François Laroussinie. 2 novembre Dept. d Informatique, ENS de Cachan

données en connaissance et en actions?

1/24. I passer d un problème exprimé en français à la réalisation d un. I expressions arithmétiques. I structures de contrôle (tests, boucles)

Architecture des ordinateurs

Raisonnement probabiliste

Polymorphisme, la classe Object, les package et la visibilité en Java... 1

Conventions d écriture et outils de mise au point

Présentation du langage et premières fonctions

Cours d Algorithmique-Programmation 2 e partie (IAP2): programmation 24 octobre 2007impérative 1 / 44 et. structures de données simples

Chp. 4. Minimisation d une fonction d une variable

Introduction à MATLAB R

Java Licence Professionnelle CISII, Cours 2 : Classes et Objets

Rappels sur les suites - Algorithme

# let rec concat l1 l2 = match l1 with [] -> l2 x::l 1 -> x::(concat l 1 l2);; val concat : a list -> a list -> a list = <fun>

Java Licence Professionnelle CISII,

Exercices types Algorithmique et simulation numérique Oral Mathématiques et algorithmique Banque PT

Programmation MacOSX / ios

Cours 1 : Introduction Ordinateurs - Langages de haut niveau - Application

IFT2255 : Génie logiciel

Baccalauréat ES/L Amérique du Sud 21 novembre 2013

2. Comprendre les définitions de classes

Structurer ses données : les tableaux. Introduction à la programmation

Langage et Concepts de ProgrammationOrientée-Objet 1 / 40

Algorithmique I. Algorithmique I p.1/??

Expression des contraintes. OCL : Object C o n t r a i n t L a n g u a g e

Le langage VHDL. Eduardo Sanchez EPFL

Structure d un programme et Compilation Notions de classe et d objet Syntaxe

Transcription:

Analyse statique et application. Typage. Analyse de flots de données. Exemples de transformations simples de programmes au niveau source. Prépa Agreg de Maths, option Info - ENS Cachan-Bretagne Thomas Gazagnaire thomas.gazagnaire@irisa.fr 14 février 2006

Plan 1 Introduction Définition du problème de l analyse statique Génération des (in)équations Résolution des (in)équations Preuves de correction 2 Analyse Data-Flow Introduction Techniques mises en jeu Exemple détaillé : Liveness Analysis 3 Typage Introduction Techniques mises en jeu 4 Transformations Exemple de transformation de programme guidé par l analyse statique

Plan 1 Introduction Définition du problème de l analyse statique Génération des (in)équations Résolution des (in)équations Preuves de correction 2 Analyse Data-Flow Introduction Techniques mises en jeu Exemple détaillé : Liveness Analysis 3 Typage Introduction Techniques mises en jeu 4 Transformations Exemple de transformation de programme guidé par l analyse statique

Définition du problème de l analyse statique Analyse statique, kesako? L analyse statique d un programme consiste à analyser ce programme sans l exécuter (en opposition avec l analyse dynamique). Consiste à annoter le programme avec des informations supplémentaires Vérification : vérifie que les annotations sont cohérentes entre elles et les précisent pour qu elles soient plus pertinentes Optimisation : utilise les annotations pour améliorer le programme en le transformant

Définition du problème de l analyse statique Exemples d analyses statique Annotations Vérification Optimisation variable initialisée non-déterminisme accès à un tableau segfault tests de borne signe des variables code mort constante pré-calculs données typées sûreté

Définition du problème de l analyse statique Séparation en 2 phases Interprétation abstraite qui génére un système d équations ou de contraintes Définition d un domaine abstrait D pour les variables Génération d un système d (in)égalité C en parcourant une représentantation adaptée du programme Preuves de correction Trouver une solution (la seule, la meilleure, la plus petite,...) Décidabilité de l analyse statique Dans le cas général, le problème de l analyse statique est indécidable. On se restreint à des analyses spécifiques et décidables.

Génération des (in)équations Définition du domaine abstrait D Definition D est l ensemble des propriétés que certaines parties du programmes peuvent vérifier D est une abstraction du comportement normal qui se focalise sur certaines activités du programme. En général on se focalise sur des propriétés liées aux variables. Exemples : D = {< 0, > 0, = 0, } pour les signes des variables D = {, } pour la définition des variables D est souvent un treillis (pour les preuves) Utilisation du produit cartésien pour complexifier les domaines (ex : signes des variables définies)

Génération des (in)équations Principe général Definition A chaque (bloc d ) instruction(s) du programme on va associer une (in)équation de variables prenant valeur dans D Il existe deux grandes familles de méthodes : les équations flot de données les systèmes d inférence

Génération des (in)équations Equations Data-Flow On manipule des équations sur des ensembles En chaque point du programme, on va dire comment l ensemble que l on regarde évolue en fonction des exécutions dynamiques possibles du programme Exemple : analyse de la validité des définitions p : a b + c out(p) : définitions valides après le point p in(p) : définitions valides avant le point p out(p) = [in(p) \ {p i p i : a...}] {p} Plus de détails dans la 2 e partie

Génération des (in)équations Système de règles d inférence Approche symbolique qui s inspire des règles de sémantique opérationnelle En chaque point du programme, on ajoute des nouvelles règles de raisonnement qui ne dépendent que de la structure de l instruction courante Exemple : typage simple Γ a : int Γ b : int Γ plus : int int int Γ plus(a, b) : int Plus de détails dans la 3 e partie

Résolution des (in)équations Résolution des (in)équations Il existe deux familles de méthodes : Celles basées sur la résolution symbolique : possibles quand Cd n est pas trop complexe Celles basées sur des résolutions itératives : on part d un élément extrémal et on converge vers un point fixe

Preuves de correction Preuves Il faut montrer que l abstraction est correcte et complète. C est pour cela qu on utilise un treillis pour D car on sait dire des choses intelligentes grâce aux connections de Galois Il faut montrer que l algorithme itératif converge. Or on sait que si f, à valeur dans un treillis, est monotone alors f à un plus petit point fixe. Et si f est continue : lpf(f) = i=0 f n ( ). Si le treillis est fini, on sait que ça converge Structure de D Si D à une structure de treillis fini on est content : les preuves sont presque déjà toutes faites

Preuves de correction Conclusion Séparation en 2 phases : Génération d un système (in)équations C à valeur sur D Résolution de C Preuves de corrections en kit si D à une structure de treillis fini

Plan 1 Introduction Définition du problème de l analyse statique Génération des (in)équations Résolution des (in)équations Preuves de correction 2 Analyse Data-Flow Introduction Techniques mises en jeu Exemple détaillé : Liveness Analysis 3 Typage Introduction Techniques mises en jeu 4 Transformations Exemple de transformation de programme guidé par l analyse statique

Introduction Introduction On veut calculer en chaque point d exécution du programme un certain nombre de propriétés qui portent sur les variables On veut que ce soit efficace pour de très gros programmes : en général on code la propriété ensembliste à vérifier sous forme de champ de bits Exemple : On a n variables x 1... x n dans notre programme et on veut savoir à tout moment lesquelles sont utile pour la suite. On code cela dans {0, 1} n. On prend des plus gros grains d exécution (plusieurs instructions au lieu d une seule). L analyse est moins précise, mais on peut l approfondir pour certains blocs

Introduction Exemples classiques Une explication avec les mains des exemples classiques : Analyse de vivacité (liveness analysis) P(x) = {variables qui sont utilisées après le point x} Validité des définitions (Reaching Definitions) P(x) = {instructions qui ont définis des variables utilisables au point x} Disponibilité des expressions (Available Expressions) P(x) = {expressions utilisables au point x}

Techniques mises en jeu Définition des ensembles Le programme est sous forme de Graphe de Flot de Contrôle (CFG) On manipule 4 ensembles Gen est l ensemble des propriétés que le grain courant va rendre vrai Kill est l ensemble des propriétés que le grain courant va rendre faux In est l ensemble des propriétés qui sont vraies juste avant le grain courant Out est l ensemble des propriétés qui sont vraies juste après le grain courant

Techniques mises en jeu Génération des équations 1 opérateur de jonction qui indique comment fusionner les informations. On utilise en général des vecteurs de bits, avec un opérateur de jonction adapté. All Path : ou AND Any Path : ou OR 2 analyses possibles In(b) = Out(p) Forward : p:prédecesseurs dynamiques de b Out(b) = Gen(b) (In(b) \ Kill(b)) Out(b) = In(s) Backward : s:successeurs dynamiques de b In(b) = Gen(b) (Out(b) \ Kill(b))

Exemple détaillé : Liveness Analysis Présentation Vivacité v est une variable vivante si elle est définie et qu elle est potentiellement utilisée plus tard. ie, une variable v est vivante si elle est utilisée dans l instruction courante et si il existe un chemin dans le passé vers une instruction qui définit v Utilisé pour repartir les variables dans les registres réels. Graphe d Interférence : deux variables interfèrent si elles sont vivantes en même temps Utilisé pour éliminer le code mort : une variable définie et pas utilisée est inutile

Exemple détaillé : Liveness Analysis Formalisation du domaine Kill(s) = Def(s) = { variables affectées (définies) au noeud s} Gen(s) = Use(s) = { variables utilisées au noeud s} In(s) = { variables qui sont vivantes à l entrée du noeud s} Out(s) = { variables qui sont vivantes en sortie du noeud s} Domaine abstrait de l analyse de vivacité D = P(V) ordonné par inclusion

Exemple détaillé : Liveness Analysis Formalisation de la génération d équations On veut quantifier sur l existence ou non d un chemin vers une définition : on utilise l opérateur de jonction On veut quantifier dans le passé : on utilise les équations d analyse en-arrière Out(b) = In(s) s:succ(b) In(b) = Gen(b) (Out(b) \ Kill(b)) Génération d équations Pour chaque instruction du programme on génére 2 équations ensemblistes. Les constantes sont les ensembles Gen(s) et Kill(s) pour tout s, et les variables sont In(s) et Out(s). Correction et Complétude?

Exemple détaillé : Liveness Analysis Formalisation de la résolution du système d équations On résoud par itération successives en partant de l ensemble vide pour chaque In et Out L ordre de réduction ne change pas le résultat MAIS une stratégie partant des noeuds finaux pour remonter aux noeuds initiaux est beaucoup plus efficace en pratique Résolution du système d équations Résolution par itération jusqu à atteindre un plus petit point fixe. L algorithme converge car D est un treillis fini, f est monotone.

Exemple détaillé : Liveness Analysis Exemple On veut faire l analyse du code suivant : a = 0; L 1 b = a + 1 c = c + b a = b 2 if a < N goto L 1 return c

Exemple détaillé : Liveness Analysis Exemple : CFG On construit (au tableau) le CFG du programme B 1 : a = 0; B 2 : b = a + 1 c = c + b a = b 2 if a < N B 3 : return c B 1 B 2, B 2 B 3 et B 2 B 2

Exemple détaillé : Liveness Analysis Exemple : Résolution state use def 1 out 1 in 2 out 2 in 3 out 3 in 6 c c c c 5 a c ac ac ac ac ac 4 b a ac bc ac bc ac bc 3 bc c bc bc bc bc bc bc 2 a b bc ac bc ac bc ac 1 a ac c ac c ac c

Exemple détaillé : Liveness Analysis Conclusion D est une famille d ensembles var = {In(s), Out(s)} s et cst = {Gen(s), Kill(s)}. C = f(var, cst) Résolution : itération de F n (In(s), Out(s) ) Méthodes d accélération : opérations sur les codages plutôt que les ensembles

Plan 1 Introduction Définition du problème de l analyse statique Génération des (in)équations Résolution des (in)équations Preuves de correction 2 Analyse Data-Flow Introduction Techniques mises en jeu Exemple détaillé : Liveness Analysis 3 Typage Introduction Techniques mises en jeu 4 Transformations Exemple de transformation de programme guidé par l analyse statique

Introduction Les types, kesako? Renseignements sur les données du programme Abstraction (Curry) Spécification (Church) Associé à la valeur de la variable ou à son nom Reconnaissance des erreurs de typage Statiquement Lors de l exécution / Pas toujours Fortes garanties lors de l exécution

Introduction Exemples Nombreux systèmes de type type simple int, float,... types énumérés bool type somme en Caml types composés array, list pointeurs, fonctions, objets,...

Techniques mises en jeu Type-Checking D = {int, float, char, t t} Uniquement des contantes de type qui sont tous spécifiés par l utilisateur Vérification de l équivalence de type C = {t 1 = t 2 } Résolution simple car juste test d égalité de structures d autres techniques dures à faire entrer dans le cadre Conversions explicites (cast) Conversions implicites (coercion)

Techniques mises en jeu Type-Inference Constantes de type + Variables de type L utilisateur précise le moins de choses possibles, le compilateur doit deviner Le compilateur associe une variable de type T x à chaque variable x du programme Chaque constructeur génère de nouvelles contraintes sur les T x On veut savoir si le programme est typable, ie. trouver Φ : T x > c ste qui réalise C

Techniques mises en jeu Types monomorphes On associe à chaque variable x du programme une variable de type T x dans un environnement de typage Γ. On a un ensemble d équations C de type qu on génère en parcourant le terme à typer. Exemple : type de fun x -> x + 1 dans Γ = on type x + 1 dans Γ = {x : T x } et C = :? on type 1 dans Γ = {x : T x } et C = : int on type x dans Γ = {x : T x } et C = : T x on type x+1 dans Γ = {x : T x } et C = {T x = int} : int on type fun x -> x+1 dans Γ = et C = : int int Ici on a mélangé la génération et la résolution comme dans beaucoup d algo de résolution de système mais on peut faire plus propre

Techniques mises en jeu Unification La résolution des équations de type, c est le même algorithme que pour l unification en programmation logique! A 1 (int A 2 ) = (A 3 bool) A 1 se traduit en formule logique : fleche(a 1, fleche(int, A 2 ) = fleche(fleche(a 3, bool), A 1 ) Algo d unification une constante s unifie uniquement avec elle même 2 structures s unifient si elles ont le même nom, le même nombre d arguments et si les arguments s unifient entre eux une variable s unifie avec n importe quoi. Si l autre chose est une constante, la variable est instanciée. Si l autre chose est une variables, elles deviennent liées.

Techniques mises en jeu Type polymorphes on veut pouvoir typer : let f = fun x -> x in (f 5, f "toto") (qui est typable en caml) types polymorphes : on rajoute un niveau, les scémas de type t = cst var t t et s = var [t] vars Γ associe un schéma S x à chaque variable x algorithmes qui mélangent génération d équations et résolutions quand on rencontre un let (comme dans W,J,...) mais on peut aussi distinguer les 2 phases pour retomber sur le cadre général

Techniques mises en jeu Conclusion D = {t} C = { contraintes de type } Résolution : unification et itération avec différentes stratégies d évaluation

Plan 1 Introduction Définition du problème de l analyse statique Génération des (in)équations Résolution des (in)équations Preuves de correction 2 Analyse Data-Flow Introduction Techniques mises en jeu Exemple détaillé : Liveness Analysis 3 Typage Introduction Techniques mises en jeu 4 Transformations Exemple de transformation de programme guidé par l analyse statique

Exemple de transformation de programme guidé par l analyse statique On veut analyser et optimiser le bout de code suivant : int toto(int x, int y) { int u =1, v=1, z, w, k; while(v > 0) { z = 5; w = 10; x = y + w; k = 2*z; u = y; v = k + u; v = x - v; } printf("x=%s, k=%s",x,k); }

Exemple de transformation de programme guidé par l analyse statique On a un domaine (un peu résumé) : D = {v, c ste (int), c opy (v), e xpr (e)} Remarque : ce D est inventé pour l occasion, généralement on fait ça avec du data-flow mais c est pour l exemple v : variable dont on ne sait rien c ste (int) : constante, avec sa valeur c copy (v) : copie de la variable v (dont on ne sait rien) e xpr (e) : variable contenant une expression arithmétique, avec son expression symbolique (sous forme d arbre par exemple) Si on veut garder la consistance des types, il va falloir faire des calculs avant l exécution! x := y avec y : c ste (5) donnera x : c ste (5) et pas x : c opy (y) x := y + z avec y : c ste (5) et z : c ste (3) donnera x : c ste (8)

Exemple de transformation de programme guidé par l analyse statique void toto(int x, int y) { int u =1, v=1, z, w, k; while(v > 0) { z = 5; w = 10; x = y + \alert{10}; k = 2*z; u = y; v = k + u; v = w - v; } printf("x=%s k=%s",x,k); }

Exemple de transformation de programme guidé par l analyse statique void toto(int x, int y) { int u =1, v=1, z, w, k; while(v > 0) { z = 5; w = 10; x = y + 10; k = 2*\alert{5}; u = y; v = k + u; v = x - v; } printf("x=%s k=%s",x,k); }

Exemple de transformation de programme guidé par l analyse statique void toto(int x, int y) { int u =1, v=1, z, w, k; while(v > 0) { z = 5; w = 10; x = y + 10; k = \alert{10}; u = y; v = k + u; v = x - v; } printf("x=%s k=%s",x,k); }

Exemple de transformation de programme guidé par l analyse statique void toto(int x, int y) { int u =1, v=1, z, w, k; while(v > 0) { z = 5; w = 10; x = y + 10; k = 10; u = y; v = \alert{10 + y}; v = x - v; } printf("x=%s k=%s",x,k); }

Exemple de transformation de programme guidé par l analyse statique void toto(int x, int y) { int u =1, v=1, z, w, k; while(v > 0) { z = 5; w = 10; x = y + 10; k = 10; u = y; v = \alert{x}; v = x - v; } printf("x=%s k=%s",x,k); }

Exemple de transformation de programme guidé par l analyse statique void toto(int x, int y) { int u =1, v=1, z, w, k; while(v > 0) { z = 5; w = 10; x = y + 10; k = 10; u = y; v = x; v = \alert{0}; } printf("x=%s k=%s",x,k); }

Exemple de transformation de programme guidé par l analyse statique void toto(int x, int y) { int u =1, v=1, z, w, k; \alert{\* while(v > 0) { *\} z = 5; w = 10; x = y + 10; k = 10; u = y; v = x; v = 0; \alert{\* } \*} printf("x=%s k=%s",x,k); }

Exemple de transformation de programme guidé par l analyse statique void toto(int x, int y) { int u =1, v=1, z, w, k; z = 5; w = 10; x = y + 10; k = 10; u = y; v = x; v = 0; printf("x=%s k=%i",x,10); }

Exemple de transformation de programme guidé par l analyse statique Analyse de vie void toto(int x, int y) { x = y + 10; printf("x=%s k=%i",x,10); }

Exemple de transformation de programme guidé par l analyse statique Conclusion J ai juste marqué les transformations du programme, mais chaque transformation est dictée par une contrainte de type Les contraintes de type sont construites et immédiatement résolues On raisonne par itération, donc il se peut qu il faille entrelacer l analyse de type et l analyse de vivacité pour obtenir un point fixe (principe des compilateurs à plusieurs phases) On a du mal à reconnaître le programme initial : le compilateur prend beaucoup d initiatives (et encore on a pas tout vu)

Conclusion Belle théorie : un domaine abstrait D, des contraintes C générées dans une première phase, et résolution de C dans une seconde, avec des belles preuves Typage et Analyse Data-Flow : même principe venant de communautés différentes, qui permettent de faire plus ou moins la même chose (avec des preuves pour le typage, et des méthodes de résolution efficaces pour l analyse data-flow) En pratique, on mélange génération et résolution de C dans des algorithmes itératifs qui convergent plus ou moins rapidement vers un point fixe Ça ne sert à rien d optimiser à la main vos programmes, le compilateur va de toute façon complètement réécrire votre code à sa sauce : seul compte la complexité de l algorithme

Références HDR Analyse statique de programmes : fondements et applications de Thomas Jensen Cours de programmation Daniel Hirshckoff Cours de compilation de François Bodin Programming Language Pragmatics de Michael Scott Compilateurs de Grune, Bal et Jacobs