380 likes | 587 Views
Java Path Finder. Pourquoi s’y intéresser ?. Tendance pour les outils de test. Pour cet exposé, test de programmes Annonces de milliers de LoC testées automatique-ment ???? Analyse statique, quoi de neuf ? Rôle du Model-Checking pour le test ? “Program Model-checking”, c’est quoi ?
E N D
Java Path Finder Pourquoi s’y intéresser ?
Tendance pour les outils de test • Pour cet exposé, test de programmes • Annonces de milliers de LoC testées automatique-ment ???? • Analyse statique, quoi de neuf ? • Rôle du Model-Checking pour le test ? • “Program Model-checking”, c’est quoi ? • “Run-time Verification”, c’est quoi ? • Alors regardons Java Path Finder … • NB: il y aurait aussi Verisoft, SLAM, BLAST, …
Histoire • Développé à la NASA depuis 1999 • Logiciel libre (sourceforge) • Auteurs : • Villem Visser • Klaus Havelund • Corina Pasareanu • etc, etc
C’est quoi Java Path Finder? • “JPF is a swiss army knife for all sort of runtime based verification” • Très spécialisé Java, mais tout Java, y compris les « threads » • Environnement pour « traiter » des programmes Java annotés • Model-checking • Simulation, et récemment exécution symbolique
Plan de l’exposé • Quelques mots sur le model-checking • Test et model-checking • Model-checking de programmes, à la JPF • Test de programmes avec Java Path Finder
Model-checking (rappel) • Le modèle est fini • Les états sont étiquetés par des propriétés • Les formules de logique temporelle sont, par exemple, des invariants, des « P1 until P2 », etc Model Checker valide Modèle contre- exemple , Formule de logique temporelle
Model-checking, principes • Exploration exhaustive du modèle • Différentes représentations du modèle et de la formule • JPF : états explicites • Exploration : DFS, BFS, etc • Arrêt dès que l’on rencontre un état déjà visité • On sort la trace courante si on rencontre un état qui ne satisfait pas la propriété => contre-exemple
Test generation using model-checking • Exploits the fact that model-checkers may yield counter-examples • Given , a required property of the SUT • Given a model M of the SUT • Model-check M for ¬ • The model-checker will reject ¬ and produce a counter-example, i.e. a trace that satisfies , i.e. a test sequence for • Popular, most model-checkers have been experienced for test generation • Nice, but…
New issues, …and good old ones • must be a formula in some temporal logic (not always convenient) • An example: • : AG(¬request (request U grant)) • ¬ : EF(request ¬(request U grant)) • One counter-example is not enough (because of the universal quantification) => exhaustivity and coverage issues • The finite model is an over-approximation of the system • Feasability, constraint solvers…
Plan de l’exposé • Quelques mots sur le model-checking • Test et model-checking • Model-checking de programmes, à la JPF • Test de programmes avec Java Path Finder
Model-checking de programmes • Le programme est le modèle • Infinité d’états • États très complexes • Problèmes de passage à l’échelle… • Représentation astucieuse des états et de leurs évolution • Exploitation de la symétrie des états • Slicing : on identifie la partie du programme qui influence la formule, et on ignore le reste • « Partial Order Reduction » • Abstraction
Que vérifie JPF? • Plusieurs modes et options • //isme : détection de « race conditions » (pb avec des objets partagés) et de « deadlocks » • Détection des exceptions non traitées • Mauvais usage de la mémoire • Assertions dans le code • assert < exp. Booléenne> • Formules LTL : fichiers .ltl, JPF utilise Bandera, et ils disent : • Note: Currently it is possible that a trace obtained while checking an LTL formula could not be properly executed during path simulation.
Le noyau de JPF JAVA • Two major concepts: • Search and JVMJPF • Search is the JVM driver • and Property evaluator • JVM is the state generator LTL or deadlock or assert Bytecode JPF: search + Java Virtual Machine Property holds Error display
La Classe Verify • JPF arrive avec une bibliothèque de classes impressionnante, qui est extensible • La classe Verify : • gov.nasa.jpf.jvm.Verify • Sert à annoter le programme • Sert à « fermer » le programme / environnement pendant la vérification : on modélise l’environnement • Quelques méthodes • public static int random(int max); • public static boolean randomBool(); • public static void beginAtomic(); • public static void endAtomic(); • ignoreIf(cond); • …
Représentation des états • Trois composants: • Threads, variables statiques (classes), variables dynamiques (objets) • Pour chaque thread, pile d’appels de méthodes • Verrous et champs de chaque classe ou objet • Compression à la SPIN: tout se passe par indices (hachage), un max de valeurs sont partagées, les mises à jour ne changent que les indices des valeurs modifiées. • Comparaison d’états efficace • Ils annoncent des millions d’états dans 512 Mb
JPF et slicing JAVA Static Analysis LTL or deadlock or assert Bytecode Sliced JAVA JPF: search + JVM Property holds Error display
Techniques appliquées au model-checking • Slicing (coupage en tranche) • Critère de slicing (souvent des points du programme) • Programme « slicé » : parties du programme qui peuvent affecter ou être affectées par le critère • Cas du model-checking : le critère est souvent lié à une propriété => tous les points du programmes affectant une variable de la propriété. • Partial Order Reduction : détermination des instructions indépendantes de thread à thread => un seul entrelacement est considéré. Analyse statique + dynamique
JPF et “Partial Order Reduction” JAVA Static Analysis LTL or deadlock or assert Bytecode POR Info JPF: search + JVM ? Property holds Error display
JPF et Abstraction JAVA Abstraction par prédicats LTL or deadlock or assert Abstract Java Bytecode JPF: search + JVM Property holds Error display
Techniques du Model-checking • Réduction par symétrie • Équivalence entre états (forme canonique) : ordre sur les noms de classes et pour les objets, unique identifiant des « NEW »+ n° d’occurrence • Forme canonique du tas • Abstraction: programmes abstraits obtenus par annotations de l’utilisateurs • Classe Abstract: spécification de prédicats • Abstract.addBoolean(“xGTy”,A.x > B.y) • Pb avec l’abstraction : sur-approximation des comportements => raffinement par essais d’exécution des contre-exemples
JPF et Analyses spécialisées JAVA LTL or deadlock or assert Analyses spécialisées Bytecode Fenêtre d’ordon- nancement JPF: search + JVM Diagnostics: deadlocks, race Property holds Error display
Exemples • Toujours les mêmes • NASA’s remote agent spacecraft control system, 1998, LISP, SPIN, deadlock en vol en 1999 • K9 Rover, 8KLOC, C++/JAVA • DEOS avionics operating system, slice de 1000 lignes de C++ traduit en 1443 lignes de Java • Ils disent analyser “routinely” des programmes de 1000 à 5000 lignes • Ils disent qu’essayer avec 100000 lignes serait « naïf »
Plan de l’exposé • Quelques mots sur le model-checking • Test et model-checking • Model-checking de programmes, à la JPF • Test de programmes avec Java Path Finder
Evaluation symbolique • C’est une extension : JPF-SE • Liée à l’abstraction • Vieille idée : King 1976! Mais généralisation aux structures dynamiques, tableaux, //isme. • Le model-checker produit et explore un arbre d’exécution symbolique • Pb des boucles…=> DFS, mais profondeur itérative, ou BFS
X >? Y [ X > Y ] y = X + Y – Y = X [ X > Y ] x = X + Y – X = Y [ X > Y ] Y - X >? 0 [ X > Y, Y – X > 0 ] END [ X > Y, Y – X <= 0 ] END Swap Valeurs symboliques int x, y; 1 : if (x > y) { 2 : x = x + y; 3 : y = x – y; 4 : x = x – y; 5 : if (x – y > 0) 6 : assert(false); } x = X, y = Y 1 1 [ X <= Y ] END [ X > Y ] x = X + Y 2 Prédicats de chemins 3 4 5 5
Exécution symbolique • Valeurs d’entrée => Valeurs symboliques • Valeurs des variables du programme : expressions symboliques • Etat : • Valeurs symboliques des variables • Prédicat de chemin • Prochaine(s) instruction(s)
Exécution symbolique généralisée • Initialisation paresseuse : les champs sont initialisés la première fois qu’ils sont accédés • Cas des références : choix non déterministe entre null, un nouvel objet (non initialisé), un objet déjà existant • Cas des valeurs primitives : nouvelle valeur symbolique • Conditionnelle : choix non déterministe de la condition ou de sa négation qui est alors ajoutée au PC courant => procedure de décision => si insatisfiabilité => retour arrière
Cela paraît tout simple • Il y a une bibliothèque de types symboliques • Par exemple : Expression est la classe des entiers symboliques, avec des méthodes symboliques add, gt,… • Les accès et affectations aux champs sont remplacés par des méthodes get et set • Les méthodes get implémentent de l’initialisation paresseuse • => Instrumentation massive • Exemple class Node { int elem; Node next;} void foo() {… if(elem > t.elem) next = t.next; } }
Instrumentation (automatique?) Class Node{ Expression elem; Node next; boolean _next_is_init = false; boolean _elem_is_init = false; static Vector v = new Vector(); static {v.add(null);} Node _new_Node() {…} Node _get_next() {…} void foo() {… if (_get_elem()._GT(t._get_elem())) _set_next(t._get_next())); } }
Il y a deux articles : ISSTA’04 et ISSTA’06 • L’un parle de red-black trees, l’autre de containers… • On engendre des séquences d’appels de méthodes par exploration exhaustive… de quoi?
Génération de tests • Exemple : les arbres équilibrés rouge-noir (cf. l’article de Korat) • Ils font du black-box (basé sur des préconditions de méthodes) et du white-box (couverture des branches) • Le model-checker explore exhaustivement soit les enchaînements de méthodes, soit l’arbre d’exécution symbolique
repOk(): conditions (1)-(5) (1) The root is BLACK (3) All paths from a node to its leaves contain the same number of black nodes. (2) Red nodes can only have black children (4) Acyclic (5) Consistent Parents
Fragment de RepOk boolean repOk(Entry e) { // root has no parent, root is black,… // RedHasOnlyBlackChildren workList = new LinkedList(); workList.add(e); while (!workList.isEmpty()) { Entry current=(Entry)workList.removeFirst(); Entry cl = current.left; Entry cr = current.right; if (current.color == RED) { if(cl != null && cl.color == RED) return false; if(cr != null && cr.color == RED) return false; } if (cl != null) workList.add(cl); if (cr != null) workList.add(cr); } // equal number of black nodes on left and right sub-tree… return true; }
Ce qu’ils font avec çà (ISSTA’04) • Ils exécutent toutes les séquences de méthodes put et remove sur un ensemble d’au plus N éléments • Ils engendrent tous les arbres non-isomorphes jusqu’à une certaine (petite) taille et ils les utilisent pour tester les méthodes • En fait, c’est RepOk + procédure de décision • Ils engendrent des tests “white-box” pour couvrir les branches des méthodes
“Decision procedures” [TACAS 2007] « JPF–SE uses the following decision procedures; they vary in the types of constraints they can handle and their efficiency. Omega library [9] – supports linear integer constraints. CVC-Lite [3] – supports integer, rational, bit vectors, and linear constraints. YICES1 [4] – supports types and operations similar to those of CVC-Lite. STP2 [2] – supports operations over bit vectors. In the JPF–SE interface, all integers are treated as bit vectors of size 32. Recently, we have also added a constraint solver, RealPaver [10] that supports linear and non-linear constraints over floating point numbers. »