Java Path Finder Pourquoi s’y intéresser ? 29/10/2008 1 Tendance pour les outils de test • Pour cet exposé, test de programmes • Annonces de milliers de LoC testées automatiquement ???? • 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, … 29/10/2008 2 Histoire • Développé à la NASA depuis 1999 • Logiciel libre (sourceforge) • Auteurs : – – – – Villem Visser Klaus Havelund Corina Pasareanu etc, etc 29/10/2008 3 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 29/10/2008 4 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 29/10/2008 5 Model-checking (rappel) valide Modèle Model Checker , Formule de logique temporelle contreexemple • 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 29/10/2008 6 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 29/10/2008 7 Test generation using modelchecking • Exploits the fact that model-checkers may yield counterexamples – 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 counterexample, i.e. a trace that satisfies , i.e. a test sequence for – Popular, most model-checkers have been experienced for test generation – Nice, but… 29/10/2008 8 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… 29/10/2008 9 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 29/10/2008 10 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 29/10/2008 11 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. 29/10/2008 12 Le noyau de JPF • Two major concepts: Search and JVMJPF • Search is the JVM driver and Property evaluator • JVM is the state generator JAVA Bytecode LTL or deadlock or assert JPF: search + Java Virtual Machine Property holds 29/10/2008 Error display 13 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); 29/10/2008 • … 14 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 29/10/2008 15 JPF et slicing Static Analysis JAVA Bytecode LTL or deadlock or assert Sliced JAVA JPF: search + JVM Property holds 29/10/2008 Error display 16 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 29/10/2008 17 JPF et “Partial Order Reduction” Static Analysis JAVA Bytecode JPF: search + JVM 29/10/2008 Property holds LTL or deadlock or assert ? Error display POR Info 18 JPF et Abstraction Abstraction par prédicats Abstract Java JAVA Bytecode LTL or deadlock or assert JPF: search + JVM 29/10/2008 Property holds Error display 19 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 29/10/2008 20 JPF et Analyses spécialisées JAVA Analyses spécialisées Fenêtre d’ordonnancement Diagnostics: deadlocks, race 29/10/2008 Bytecode LTL or deadlock or assert JPF: search + JVM Property holds Error display 21 Le bazar global 29/10/2008 22 29/10/2008 23 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 » 29/10/2008 24 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 29/10/2008 25 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 29/10/2008 26 Valeurs symboliques Swap int x, y; x = X, y = Y 1 : if (x > y) { X >? Y 1 [X>Y]x=X+Y 1 2: x = x + y; [ X <= Y ] END 3: y = x – y; 4: x = x – y; 5: if (x – y > 0) 2 [X>Y]y=X+Y–Y=X Prédicats de chemins 3 [X>Y]x=X+Y–X=Y 4 [ X > Y, Y – X <= 0 ] END 29/10/2008 assert(false); } [ X > Y ] Y - X >? 0 5 6: 5 [ X > Y, Y – X > 0 ] END 27 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) 29/10/2008 28 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 29/10/2008 29 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; } } 29/10/2008 30 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())); } 29/10/2008 31 } • 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? 29/10/2008 32 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 29/10/2008 33 repOk(): conditions (1)-(5) (3) All paths from a node to its leaves contain the same number of black nodes. (1) The root is BLACK (2) Red nodes can only have black children (4) Acyclic (5) Consistent Parents 29/10/2008 34 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; 29/10/2008 } 35 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 29/10/2008 36 “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 29/10/2008 37 floating point numbers. »