Predicate Abstraction for Software Verification Shaz Qadeer Compaq Systems Research Center (joint work with Cormac Flanagan)

Slides:



Advertisements
Similar presentations
Copyright © 2006 The McGraw-Hill Companies, Inc. Programming Languages 2nd edition Tucker and Noonan Chapter 18 Program Correctness To treat programming.
Advertisements

Extended Static Checking for Java Cormac Flanagan K. Rustan M. Leino Mark Lillibridge Greg Nelson James B. Saxe Raymie Stata Compaq SRC 18 June 2002 PLDI02,
Demand-driven inference of loop invariants in a theorem prover
Technologies for finding errors in object-oriented software K. Rustan M. Leino Microsoft Research, Redmond, WA Lecture 1 Summer school on Formal Models.
Technologies for finding errors in object-oriented software K. Rustan M. Leino Microsoft Research, Redmond, WA Lecture 0 Summer school on Formal Models.
Automated Theorem Proving Lecture 1. Program verification is undecidable! Given program P and specification S, does P satisfy S?
Synthesis, Analysis, and Verification Lecture 04c Lectures: Viktor Kuncak VC Generation for Programs with Data Structures “Beyond Integers”
Semantics Static semantics Dynamic semantics attribute grammars
ICE1341 Programming Languages Spring 2005 Lecture #6 Lecture #6 In-Young Ko iko.AT. icu.ac.kr iko.AT. icu.ac.kr Information and Communications University.
Abstraction and Modular Reasoning for the Verification of Software Corina Pasareanu NASA Ames Research Center.
Automated Software Verification with a Permission-Based Logic 20 th June 2014, Zürich Malte Schwerhoff, ETH Zürich.
Program Representations. Representing programs Goals.
Rigorous Software Development CSCI-GA Instructor: Thomas Wies Spring 2012 Lecture 13.
Partial correctness © Marcelo d’Amorim 2010.
ISBN Chapter 3 Describing Syntax and Semantics.
Copyright © 2006 Addison-Wesley. All rights reserved. 3.5 Dynamic Semantics Meanings of expressions, statements, and program units Static semantics – type.
CS 355 – Programming Languages
Formal Methods of Systems Specification Logical Specification of Hard- and Software Prof. Dr. Holger Schlingloff Institut für Informatik der Humboldt.
Avoiding Exponential Explosion: Generating Compact Verification Conditions Cormac Flanagan and James B. Saxe Compaq Systems Research Center With help from.
ESC Java. Static Analysis Spectrum Power Cost Type checking Data-flow analysis Model checking Program verification AutomatedManual ESC.
Hoare-style program verification K. Rustan M. Leino Guest lecturer Rob DeLine’s CSE 503, Software Engineering University of Washington 26 Apr 2004.
K. Rustan M. Leino Research in Software Engineering (RiSE) Microsoft Research, Redmond, WA part 0 Summer School on Logic and Theorem-Proving in Programming.
Modular Verification of Multithreaded Software Shaz Qadeer Compaq Systems Research Center Shaz Qadeer Compaq Systems Research Center Joint work with Cormac.
Building a program verifier K. Rustan M. Leino Microsoft Research, Redmond, WA 10 May 2006 Guest lecture, Shaz Qadeer’s cse599f, Formal Verification of.
Houdini: An Annotation Assistant for ESC/Java Cormac Flanagan and K. Rustan M. Leino Compaq Systems Research Center.
ESC Java. Static Analysis Spectrum Power Cost Type checking Data-flow analysis Model checking Program verification AutomatedManual ESC.
Review: forward E { P } { P && E } TF { P && ! E } { P 1 } { P 2 } { P 1 || P 2 } x = E { P } { \exists … }
Predicate Abstraction for Software Verification Cormac Flanagan Shaz Qadeer Compaq Systems Research Center.
Thread-Modular Verification Shaz Qadeer Joint work with Cormac Flanagan Stephen Freund Shaz Qadeer Joint work with Cormac Flanagan Stephen Freund.
Review: forward E { P } { P && E } TF { P && ! E } { P 1 } { P 2 } { P 1 || P 2 } x = E { P } { \exists … }
Well-cooked Spaghetti: Weakest-Precondition of Unstructured Programs Mike Barnett and Rustan Leino Microsoft Research Redmond, WA, USA.
Chair of Software Engineering Automatic Verification of Computer Programs.
Describing Syntax and Semantics
Formal Verification of SpecC Programs using Predicate Abstraction Himanshu Jain Daniel Kroening Edmund Clarke Carnegie Mellon University.
Extended Static Checking for Java or Light-weight formal methods: from objects to components Joint work with Cormac Flanagan, Mark Lillibridge, Greg Nelson,
C. FlanaganType Systems for Multithreaded Software1 Cormac Flanagan UC Santa Cruz Stephen N. Freund Williams College Shaz Qadeer Microsoft Research.
Software Engineering Prof. Dr. Bertrand Meyer March 2007 – June 2007 Chair of Software Engineering Static program checking and verification Slides: Based.
Cosc 2150: Computer Organization
Extended Static Checking for Java  ESC/Java finds common errors in Java programs: null dereferences, array index bounds errors, type cast errors, race.
CS 363 Comparative Programming Languages Semantics.
Computer Science School of Computing Clemson University Discrete Math and Reasoning about Software Correctness Joseph E. Hollingsworth
Synthesis, Analysis, and Verification Lecture 05a Lectures: Viktor Kuncak Programs with Data Structures: Assertions for Accesses. Dynamic Allocation.
Application: Correctness of Algorithms Lecture 22 Section 4.5 Fri, Mar 3, 2006.
Propositional Calculus CS 270: Mathematical Foundations of Computer Science Jeremy Johnson.
Formal verification of skiplist algorithms Student: Trinh Cong Quy Supervisor: Bengt Jonsson Reviewer: Parosh Abdulla.
Application: Correctness of Algorithms Lecture 22 Section 4.5 Fri, Feb 18, 2005.
Semantics In Text: Chapter 3.
COP4020 Programming Languages Introduction to Axiomatic Semantics Prof. Robert van Engelen.
Extended Static Checking for Java or Light-weight formal methods: from objects to components Joint work with Cormac Flanagan, Mark Lillibridge, Greg Nelson,
Extended Static Checking for Java Cormac Flanagan Joint work with: Rustan Leino, Mark Lillibridge, Greg Nelson, Jim Saxe, and Raymie Stata.
Model Checking for Simple Java Programs Taehoon Lee, Gihwon Kwon Department of Computer Science Kyonggi University, Korea IWFST, Shanghai, China,
Specifying and verifying programs in Spec# K. Rustan M. Leino Microsoft Research, Redmond, WA, USA Invited talk, PSI 2006 Novosibirsk, Russia 27 June 2006.
K. Rustan M. Leino Research in Software Engineering (RiSE) Microsoft Research, Redmond, WA part 2 International Summer School Marktoberdorf Marktoberdorf,
This Week Lecture on relational semantics Exercises on logic and relations Labs on using Isabelle to do proofs.
Extended Static Checking for Java Cormac Flanagan Joint work with: Rustan Leino, Mark Lillibridge, Greg Nelson, Jim Saxe, and Raymie Stata Compaq Systems.
/ PSWLAB Thread Modular Model Checking by Cormac Flanagan and Shaz Qadeer (published in Spin’03) Hong,Shin Thread Modular Model.
A Calculus of Atomic Actions Tayfun Elmas, Shaz Qadeer and Serdar Tasiran POPL ‘ – Seminar in Distributed Algorithms Cynthia Disenfeld 27/05/2013.
CSC3315 (Spring 2009)1 CSC 3315 Languages & Compilers Hamid Harroud School of Science and Engineering, Akhawayn University
Using Alcoa to Specify a UNIX File System Specification of some structures and operations in a File System.
Chapter 2: Algorithm Discovery and Design Invitation to Computer Science.
A Calculus of Atomic Actions Serdar Tasiran Koc University, Istanbul, Turkey Tayfun ElmasShaz Qadeer Koc University Microsoft Research.
Formal Verification – Robust and Efficient Code Lecture 1
Weakest Precondition of Unstructured Programs
Further with Hoare Logic Sections 6.12, 6.10, 6.13
Hoare-style program verification
Over-Approximating Boolean Programs with Unbounded Thread Creation
Hoare-style program verification
Java Modeling Language (JML)
COP4020 Programming Languages
Presentation transcript:

Predicate Abstraction for Software Verification Shaz Qadeer Compaq Systems Research Center (joint work with Cormac Flanagan)

Systems software OS components –file system, buffer cache manager Abstract from low-level to high-level operations –tedious low-level programming detail Expected to work –with multiple concurrent clients –in the presence of crashes

Outline Background –verification condition –strongest postcondition –loop invariants Inferring loop invariants –predicate abstraction –universally-quantified invariants Frangipani Related work

Verification condition x := a; if (x < b) { x := b; } assert x = max(a,b); sp(P,true)  x  a  x  b Program P Check for validity:

Statement S x := e A ; B assume e A B while {I} e do B end Guarded command language (Dijkstra 76) Variables have arbitrary values in program’s initial state if e then A else B end  (assume e ; A) (assume  e ; B)

Strongest postcondition semantics sp(S,Q)  y.(Q[x  y]  x=e[x  y]) sp(B,sp(A,Q)) e  Q sp(A,Q)  sp(B,Q) Statement S x := e A ; B assume e A B Denote sp(S, true) by sp(S)

Checking loop invariants Given loop Need to check –Invariant holds on entry to loop sp( C )  I –Invariant holds at end of every iteration sp( C; H; assume I  e; B)  I where H = havoc variables modified in B C; {I} while e do B end

Desugaring loops S = “while {I} e do B end” H = havoc variables modified in B desugar(S) = assert I ; H ; assume I ; ( (assume e ; B; assert I; assume false) assume  e)

Example assume 0 < a.length; i := 0; while (i < a.length) { a[i] := 0; i := i + 1; } assert a[0] = 0; {  int j; 0 <= j  j < i  a[j] = 0, 0<=i}

Translation assume 0 < a.length; i := 0; assert  int j; 0 <= j  j < i  a[j] = 0; assert 0 <= i; havoc a[*], i; assume  int j; 0 <= j  j < i  a[j] = 0; assume 0 <= i; ( assume (i < a.length); a[i] := 0; i := i + 1; assert  int j; 0 <= j  j < i  a[j] = 0; assert 0 <= i; assume false;) assume  (i < a.length) assert a[0] = 0;

ESC/Java with loop invariants loop_invariant i >= 0; loop_invariant 0 <= spot; loop_invariant spot <= MAXDIRENTRY; loop_invariant (\forall int j; 0 <= j && j < i && bdisk[addr].dirEntries[j].inum != DIRENTRY_UNUSED ==> bdisk[addr].dirEntries[j].name != name); loop_invariant (\forall int j; spot == MAXDIRENTRY && 0 bdisk[addr].dirEntries[j].inum != DIRENTRY_UNUSED); loop_invariant spot == MAXDIRENTRY || bdisk[addr].dirEntries[spot].inum == DIRENTRY_UNUSED; loop_invariant (\forall DirEntry t; t != de ==> t.name == \old(t.name)); loop_invariant (\forall DirEntry t; t != de ==> t.inum == \old(t.inum)); loop_invariant (\forall DirEntry t; t.inum == FS.DIRENTRY_UNUSED || (0 <= t.inum && t.inum < FS.IMAX)); */ for (i = 0; i < cwd.inode.length; i++) { GetDirEntry(de, addr, i); if (de.inum != DIRENTRY_UNUSED && de.name == name) { return ERROR; } if (de.inum == DIRENTRY_UNUSED && spot == MAXDIRENTRY) { spot = i; }

Outline Background –verification condition –strongest postcondition –loop invariants Inferring loop invariants –predicate abstraction –universally-quantified invariants Frangipani Related work

Inferring loop invariants Could try –I 0 = sp( C ) –I n+1 = I n  sp( C; H; assume I n  e; B) I n is an invariant for first n iterations Problem: May not converge C; {I} while e do B end

Divergence State Space I0I0 I1I1 I2I2 InIn...

Predicate abstraction Invariant is boolean combination of predicates Split problem into two parts 1Find a suitable set of predicates 2Find the boolean combination of these predicates

Predicate abstraction (contd.) Predicates over program variables –a = expr1, b = expr2, c = expr3, d = expr4  : boolean expression over {a,b,c,d}  formula over program variables  : formula over program variables  boolean expression over {a, b, c, d}  (F) = least boolean function G over {a,b,c,d} such that F   (G)

Abstract state space Predicates { a, b, c, d } They generate an abstract space of size 2 4 = 16 a  b a  b  a  b abab cdcd c  d  c  d cdcd F  (F) State Space

Inferring loop invariants Compute –I 0 =  (sp( C )) –I n+1 = I n   (sp( C; H; assume E   (I n) ; B)) Converges yielding valid loop invariant –Best loop invariant for the given predicates

Method 1 (slow!) Is F  a  b  c  d satisfiable? No! Can compute  (F) by asking 2 n such queries a  b a  b  a  b abab cdcd c  d  c  d cdcd F  (F) XXXX X X XX X XX

Method 2 (Das-Dill-Park 99) Order the variables: a < b < c < d a b c FaFa FabFab F  a  b  c F  a  b  (F) a  b a  b  a  b abab cdcd c  d  c  d cdcd F XXXX X X XX X XX O(2 n+1 ) queries Sensitive to ordering

Method 3 (Shankar-Saidi 99) O(3 n ) queries No ordering required Queries of size 1: F  a, F  a, F  b, etc. Number = n C 1  2 1 Queries of size 2: F  a  b, F  a  b, etc. Number = n C 2  2 2 Queries of size n:... Number = n C n  2 n....

New method F  a  b  c  d ? No! a  b a  b  a  b abab cdcd c  d  c  d cdcd F  (F) XXXX X X XX X XX F  a  c  d ? No! F  c  d ? No! Removed 1/4 of state space in 3 queries! =  (  c   d)  (  a   c)  (  a   b)  ( c   d)

Universally-quantified loop invariants loop_invariant i >= 0; loop_invariant 0 <= spot; loop_invariant spot <= MAXDIRENTRY; loop_invariant (\forall int j; 0 <= j && j < i && bdisk[addr].dirEntries[j].inum != DIRENTRY_UNUSED ==> bdisk[addr].dirEntries[j].name != name); loop_invariant (\forall int j; spot == MAXDIRENTRY && 0 bdisk[addr].dirEntries[j].inum != DIRENTRY_UNUSED); loop_invariant spot == MAXDIRENTRY || bdisk[addr].dirEntries[spot].inum == DIRENTRY_UNUSED; loop_invariant (\forall DirEntry t; t != de ==> t.name == \old(t.name)); loop_invariant (\forall DirEntry t; t != de ==> t.inum == \old(t.inum)); loop_invariant (\forall DirEntry t; t.inum == FS.DIRENTRY_UNUSED || (0 <= t.inum && t.inum < FS.IMAX)); */ for (i = 0; i < cwd.inode.length; i++) { GetDirEntry(de, addr, i); if (de.inum != DIRENTRY_UNUSED && de.name == name) { return ERROR; } if (de.inum == DIRENTRY_UNUSED && spot == MAXDIRENTRY) { spot = i; }

Inferring  -quantified loop invariants assume 0 < a.length; i := 0; loop_invariant 0 <= i,  int j; 0 <= j  j < i  a[j] = 0 */ while (i < a.length) { a[i] := 0; i := i + 1; } assert a[0] = 0;

Inferring  -quantified loop invariants assume 0 < a.length; i := 0; loop_predicate 0 <= i,  int j; 0 <= j  j < i  a[j] = 0 */ while (i < a.length) { a[i] := 0; i := i + 1; } assert a[0] = 0;

Inferring  -quantified loop invariants assume 0 < a.length; i := 0; skolem_constant int j */ loop_predicate 0 <= i, 0 <= j, j < i, a[j] = 0 */ while (i < a.length) { a[i] := 0; i := i + 1; } assert a[0] = 0;

Inferring  -quantified loop invariants I 0 =  (sp(i := 0)) I n+1 = I n   (sp(i := 0; havoc i, a[*]; assume I n  i < a.length; a[i] := 0; i := i+1)) loop_predicate 0 <= i, 0 <= j, j < i, a[j] = 0 */ TFTF TFTTTTFFTTFT I0I0 TTTT I1I1

Inferring  -quantified loop invariants loop_predicate 0 <= i, 0 <= j, j < i, a[j] = 0 */ TFTF TFTTTTFFTTFT TTTT I0I0 I1I1  0  i   (0  j)   (j < i)  a[j] = 0  0  j  j < i

Inferring  -quantified loop invariants loop_predicate 0 <= i, 0 <= j, j < i, a[j] = 0 */ TFTF TFTTTTFFTTFT TTTT I0I0 I1I1  0  i   int j; 0  j  j < i  a[j] = 0   int j; 0  j  j < i

Outline Background –verification condition –strongest postcondition –loop invariants Inferring loop invariants –predicate abstraction –universally-quantified invariants Frangipani Related work

Frangipani Distributed file system (Thekkath, Mann, Lee 1997) Built on top of Petal virtual disk (Lee, Thekkath 1996) Implements the file abstraction from the virtual disk block abstraction Exports file and directory operations - create, delete, rename etc. - to clients

Verification Loop invariant inference built on top of ESC/Java (Detlefs, Leino, Nelson, Saxe 1998) ESC/Java uses automatic theorem prover Simplify (Nelson 81) Frangipani data structures and “create” modeled abstractly in Java Assume –single thread of execution –no crashes

... ibusy idisk bdisk bbusy F TT TT FFF FF F F Inode { int inum; int addr; int mode; int length; } Block { int addr; Entry[] entries; } Entry { String name; int inum; } addr Data structures on disk: Data structures in memory:... vArray vbusy TTFF T F vArray contains inodes distinct entries must contain distinct inodes itov: int  int

invariant  int i, j: vbusy[i]  ((vArray[i].inum = j)  (itov[j] = i)); invariant  int i: ibusy[i]  bbusy[idisk[i].addr]; invariant idisk  bdisk; invariant  int i: idisk[i]  null  idisk[i].inum = i;. */ requires vbusy[num]  vArray[num].mode = DIR */ ensures \result = ERROR  there is an entry with name s in directory vArray[num] */ int create(int num, String s) {. }

Main loop in “create” loop_invariant i >= 0; loop_invariant 0 <= spot; loop_invariant spot <= MAXDIRENTRY; loop_invariant (\forall int j; 0 <= j && j < i && bdisk[addr].dirEntries[j].inum != DIRENTRY_UNUSED ==> bdisk[addr].dirEntries[j].name != name); loop_invariant (\forall int j; spot == MAXDIRENTRY && 0 bdisk[addr].dirEntries[j].inum != DIRENTRY_UNUSED); loop_invariant spot == MAXDIRENTRY || bdisk[addr].dirEntries[spot].inum == DIRENTRY_UNUSED; loop_invariant (\forall DirEntry t; t != de ==> t.name == \old(t.name)); loop_invariant (\forall DirEntry t; t != de ==> t.inum == \old(t.inum)); loop_invariant (\forall DirEntry t; t.inum == FS.DIRENTRY_UNUSED || (0 <= t.inum && t.inum < FS.IMAX)); */ for (i = 0; i < cwd.inode.length; i++) { GetDirEntry(de, addr, i); if (de.inum != DIRENTRY_UNUSED && de.name == name) { return ERROR; } if (de.inum == DIRENTRY_UNUSED && spot == MAXDIRENTRY) { spot = i; }

Performance

Related work Inferring/computing loop invariants Predicate abstraction –Graf-Saidi 97 –Bensalem-Lakhnech-Owre 98, Colon-Uribe 98 –Saidi-Shankar 99, Das-Dill-Park 99 –Ball-Majumdar-Millstein-Rajamani 2001

Future Work Heuristics for generating predicates Multiple threads –locks, semaphores,... –thread-modular reasoning Linked lists, reachability Target C