Extended Static Checking for Java Cormac Flanagan Slides courtesy of Rustan Leino.

Slides:



Advertisements
Similar presentations
Advanced programming tools at Microsoft
Advertisements

Joint work with Mike Barnett, Robert DeLine, Manuel Fahndrich, and Wolfram Schulte Verifying invariants in object-oriented programs K. Rustan M. Leino.
Copyright © 2006 The McGraw-Hill Companies, Inc. Programming Languages 2nd edition Tucker and Noonan Chapter 18 Program Correctness To treat programming.
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
Writing specifications for object-oriented programs K. Rustan M. Leino Microsoft Research, Redmond, WA, USA 21 Jan 2005 Invited talk, AIOOL 2005 Paris,
1 Towards a Verifying Compiler: The Spec# Approach Wolfram Schulte Microsoft Research Formal Methods 2006 Joint work with Rustan Leino, Mike Barnett, Manuel.
Technologies for finding errors in object-oriented software K. Rustan M. Leino Microsoft Research, Redmond, WA Lecture 3 Summer school on Formal Models.
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?
Challenges in increasing tool support for programming K. Rustan M. Leino Microsoft Research, Redmond, WA, USA 23 Sep 2004 ICTAC Guiyang, Guizhou, PRC joint.
In this episode of The Verification Corner, Rustan Leino talks about Loop Invariants. He gives a brief summary of the theoretical foundations and shows.
Semantics Static semantics Dynamic semantics attribute grammars
Abstraction and Modular Reasoning for the Verification of Software Corina Pasareanu NASA Ames Research Center.
Rigorous Software Development CSCI-GA Instructor: Thomas Wies Spring 2012 Lecture 11.
1 Symbolic Execution for Model Checking and Testing Corina Păsăreanu (Kestrel) Joint work with Sarfraz Khurshid (MIT) and Willem Visser (RIACS)
The Java Modeling Language JML Erik Poll Digital Security Radboud University Nijmegen.
JML and ESC/Java2: An Introduction Karl Meinke School of Computer Science and Communication, KTH.
272: Software Engineering Fall 2008 Instructor: Tevfik Bultan Lecture 3: Java Modeling Language and Extended Static Checking.
Automatic Discovery of Software Contract Work in progress Yishai Feldman, Leon Gendler.
CS 355 – Programming Languages
Dept. of Computer Science A Runtime Assertion Checker for the Java Modeling Language (JML) Yoonsik Cheon and Gary T. Leavens SERP 2002, June 24-27, 2002.
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.
1 Automatic Software Model Checking via Constraint Logic Programming Cormac Flanagan Systems Research Center HP Labs.
ESC Java. Static Analysis Spectrum Power Cost Type checking Data-flow analysis Model checking Program verification AutomatedManual ESC.
Proof-system search ( ` ) Interpretation search ( ² ) Main search strategy DPLL Backtracking Incremental SAT Natural deduction Sequents Resolution Main.
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.
ECI 2007: Specification and Verification of Object- Oriented Programs Lecture 1.
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.
Some administrative stuff Class mailing list: –send to with the command “subscribe”
Predicate Abstraction for Software Verification Shaz Qadeer Compaq Systems Research Center (joint work with Cormac Flanagan)
Copyright © 2006 The McGraw-Hill Companies, Inc. Programming Languages 2nd edition Tucker and Noonan Chapter 18 Program Correctness To treat programming.
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 … }
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.
Using and Building an Automatic Program Verifier K. Rustan M. Leino Research in Software Engineering (RiSE) Microsoft Research, Redmond Lecture 5 LASER.
CMPSC 272: Software Engineering Spring 2003 Instructor: Tevfik Bultan Extended Static Checking.
Jonathan Kuhn Robin Mange EPFL-SSC Compaq Systems Research Center Flanagan, Leino, Lillibridge, Nelson, Saxe and Stata.
Extended Static Checking for Java or Light-weight formal methods: from objects to components Joint work with Cormac Flanagan, Mark Lillibridge, Greg Nelson,
Software Engineering Prof. Dr. Bertrand Meyer March 2007 – June 2007 Chair of Software Engineering Static program checking and verification Slides: Based.
Inferring Specifications to Detect Errors in Code Mana Taghdiri Presented by: Robert Seater MIT Computer Science & AI Lab.
Extended Static Checking for Java  ESC/Java finds common errors in Java programs: null dereferences, array index bounds errors, type cast errors, race.
Using and Building an Automatic Program Verifier K. Rustan M. Leino Research in Software Engineering (RiSE) Microsoft Research, Redmond Lecture 3 Marktoberdorf.
Houdini, an annotation assistant for ESC/Java K. Rustan M. Leino Compaq SRC Joint work with Cormac Flanagan K. Rustan M. Leino Compaq SRC Joint work with.
Applications of extended static checking K. Rustan M. Leino Compaq SRC K. Rustan M. Leino Compaq SRC Systems Research Center Invited talk, SAS’01, Paris,
Today’s Agenda  Quick Review  Continue on JML Formal Methods in Software Engineering1.
CIS 771: Software Specifications Lecture 18: Specifying and Checking Partial Properties of Java Code Copyright , Matt Dwyer, John Hatcliff, and.
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.
Specifying and verifying programs in Spec# K. Rustan M. Leino Microsoft Research, Redmond, WA, USA Invited talk, PSI 2006 Novosibirsk, Russia 27 June 2006.
Institute for Applied Information Processing and Communications (IAIK) – Secure & Correct Systems 1 Static Checking  note for.
Extended Static Checking for Java Cormac Flanagan Joint work with: Rustan Leino, Mark Lillibridge, Greg Nelson, Jim Saxe, and Raymie Stata Compaq Systems.
Combining Static and Dynamic Reasoning for Bug Detection Yannis Smaragdakis and Christoph Csallner Elnatan Reisner – April 17, 2008.
/ PSWLAB Evidence-Based Analysis and Inferring Preconditions for Bug Detection By D. Brand, M. Buss, V. C. Sreedhar published in ICSM 2007.
ESCJ 14: ESC/Java Project Review Slides March 6th, 1997.
CSC3315 (Spring 2009)1 CSC 3315 Languages & Compilers Hamid Harroud School of Science and Engineering, Akhawayn University
Extended Static Checking for Java
Dafny An automatic program verifier for functional correctness
Further with Hoare Logic Sections 6.12, 6.10, 6.13
Hoare-style program verification
Hoare-style program verification
Dafny An automatic program verifier for functional correctness
Java Modeling Language (JML)
Assertions References: internet notes; Bertrand Meyer, Object-Oriented Software Construction; 4/25/2019.
Presentation transcript:

Extended Static Checking for Java Cormac Flanagan Slides courtesy of Rustan Leino

Motivation

Software development problem Software construction and maintenance are expensive Reliability is costly and difficult to achieve

Vision Increased programmer productivity and program reliability through increased rigor Record design decisions +Utilize automatic checking =Detect more errors and reduce costs

User's view Program with specifications Error messages public class Bag { private int[] a; private int n; invariant 0 <= n && n <= a.length; public int[] initialElements) { n = initialElements.length; a = new int[n]; System.arraycopy(initialElements, 0, a, 0, n); } public void add(int x) { if (n == a.length) { int[] b = new int[2*(a.length+1)]; System.arraycopy(a, 0, b, 0, n); a = b; } a[n] = x; n++; } public int extractMin() { int m = Integer.MAX_VALUE; int mindex = 0; for (int i = 0; i < n; i++) { if (a[i] < m) { mindex = i; m = a[i]; } } if (0 < n) { n--; a[mindex] = a[n]; } return m; } // The program text continues down here, but if you’re // reading this, you probably aren’t paying attention to // the talk. Bag.java:18: Array index possibly too large

Extended Static Checker for Java (ESC/Java) Built at Systems Research Center Input: Java + user-supplied annotations Annotation language captures programmer design decisions Powered by – weakest precondition semantics – automatic theorem proving Performs modular checking

ESC/Java demo

Program checker design tradeoffs Missed errors Spurious warnings Annotation overhead Performance

ESC/Java architecture Translator Annotated Java program Verification condition Counterexample context Warning messages Automatic theorem prover Post processor Valid Resource exhausted

Tool architecture, detail Annotated Java program Verification condition Counterexample context Warning messages Automatic theorem prover Post processor Sugared command Primitive command Passive command Translator

Annotated Java program Verification condition Counterexample context Warning messages Automatic theorem prover Post processor Sugared command Primitive command Passive command Translator Tool architecture, detail Annotated Java program Verification condition Counterexample context Warning messages Automatic theorem prover Post processor Sugared command Primitive command Passive command Translator

Annotated Java program Verification condition Counterexample context Warning messages Automatic theorem prover Post processor Sugared command Primitive command Passive command Translator Annotation language Simple – non_null Method annotations – requires E; – ensures E; – exsures (T x) E; – modifies w; Object invariants – invariant E;

Annotated Java program Verification condition Counterexample context Warning messages Automatic theorem prover Post processor Sugared command Primitive command Passive command Translator Annotation language Simple – non_null Method annotations – requires E; – modifies w; – ensures E; – exsures (T x) E; Object invariants – invariant E;

Annotated Java program Verification condition Counterexample context Warning messages Automatic theorem prover Post processor Sugared command Primitive command Passive command Translator Annotation language Specification expressions – side-effect free Java expressions no ++, no method calls – result ensures result >= 0; – old(E) ensures x == old(x)+1; – (forall T x; E), (exists T x; E), ==> (forall int j; 0 a[j] > 0);

Annotated Java program Verification condition Counterexample context Warning messages Automatic theorem prover Post processor Sugared command Primitive command Passive command Translator Annotation language Specification expressions – side-effect free Java expressions no ++, no method calls – result ensures result >= 0; – old(E) ensures x == old(x)+1; – (forall T x; E), (exists T x; E), ==> (forall int j; 0 a[j] > 0);

Annotated Java program Verification condition Counterexample context Warning messages Automatic theorem prover Post processor Sugared command Primitive command Passive command Translator Annotation language Miscellaneous – assert E; – assume E; assume x >= 0; // because x == y*y – nowarn x = a[j]; nowarn – axiom E; axiom (forall int x; x ≫ 2 >= 0); Concurrency, ghost variables

Annotated Java program Verification condition Counterexample context Warning messages Automatic theorem prover Post processor Sugared command Primitive command Passive command Translator Sugared commands S,T::=assert E |assume E |x = E |raise |S ; T |S ! T |S [] T |loop {inv E} S  T end |call x = m(E) |…

Annotated Java program Verification condition Counterexample context Warning messages Automatic theorem prover Post processor Sugared command Primitive command Passive command Translator Sugared commands x = t.f.g; assert t ≠ null; tmp = select(f, t); assert tmp ≠ null; x = select(g, tmp) if (x = 0; */ (assume x < 0; x = -x []assume ¬(x < 0) ); assert x >= 0

Annotated Java program Verification condition Counterexample context Warning messages Automatic theorem prover Post processor Sugared command Primitive command Passive command Translator Sugared commands x = t.f.g; assert t ≠ null); tmp = select(f, t); assert tmp ≠ null); x = select(g, tmp) if (x = 0; */ (assume x < 0; assume lblpos(“Then^280:7”, true); x = -x []assume ¬ (x < 0); assume lblpos(“Else^280:7”, true) ); assert x >= 0

Annotated Java program Verification condition Counterexample context Warning messages Automatic theorem prover Post processor Sugared command Primitive command Passive command Translator Primitive commands S,T::=assert E |assume E |x = E |raise |S ; T |S ! T |S [] T |loop {inv E} S  T end |call x = m(E) |…

Annotated Java program Verification condition Counterexample context Warning messages Automatic theorem prover Post processor Sugared command Primitive command Passive command Translator Primitive commands requires Pre; modifies w; ensures Post; void m(U u); call x = m(E) var u in u = E; assert Pre; var w 0 in w 0 = w; havoc w; assume Post; x = result end

|raise |S ; T |S ! T |S [] T Annotated Java program Verification condition Counterexample context Warning messages Automatic theorem prover Post processor Sugared command Primitive command Passive command Translator Passive commands S,T::=assert E |assume E |x = E

private int scanPunctuation(int nextchr) { try { boolean possibleFloatingPointNumber = (nextchr == '.'); text[0] = (char)nextchr; textlen = 1; m_in.mark(); // All paths out of the try must unmark the stream!! PunctuationPrefixTree prefix = punctuationTable; PunctuationPrefixTree lastPunctuation = prefix; int lastPunctuationLength = 0; int index = nextchr - '!'; if (index < 0 || PunctuationPrefixTree.CHILDLEN <= index) prefix = null; else prefix = prefix.children[nextchr - '!']; nextchr = m_in.read(); if (possibleFloatingPointNumber && Character.isDigit((char)nextchr)) { m_in.clearMark(); return finishFloatingPointLiteral(nextchr); } this.append(nextchr); if (prefix != null && prefix.code != TagConstants.NULL) { lastPunctuation = prefix; lastPunctuationLength = textlen - 1; m_in.mark(); } while(prefix != null) { index = nextchr - '!'; if (index < 0 || PunctuationPrefixTree.CHILDLEN <= index) prefix = null; else prefix = prefix.children[nextchr - '!']; nextchr = m_in.read(); this.append(nextchr); if (prefix != null && prefix.code != TagConstants.NULL) { lastPunctuation = prefix; lastPunctuationLength = textlen - 1; m_in.mark(); } m_in.reset(); textlen = lastPunctuationLength; endingLoc = m_in.getLocation(); ttype = lastPunctuation.code; if (ttype != TagConstants.C_COMMENT&& ttype != TagConstants.EOL_COMMENT) nextchr = m_in.read(); return ttype; } catch (IOException e) { m_in.clearMark(); ErrorSet.fatal(m_in.getLocation(), e.toString()); return TagConstants.NULL; // Dummy }

Annotated Java program Verification condition Counterexample context Warning messages Automatic theorem prover Post processor Sugared command Primitive command Passive command Translator Passive commands if (x = 0; */ (assume x 0 < 0; x 1 = -x 0 ; x 2 = x 1 []assume ¬(x 0 < 0); x 2 = x 0 ); assert x 2 >= 0

Annotated Java program Verification condition Counterexample context Warning messages Automatic theorem prover Post processor Sugared command Primitive command Passive command Translator Passive commands if (x = 0; */ (assume x 0 < 0; assume x 1 == -x 0 ; assume x 2 == x 1 []assume ¬(x 0 < 0); assume x 2 == x 0 ); assert x 2 >= 0

Annotated Java program Verification condition Counterexample context Warning messages Automatic theorem prover Post processor Sugared command Primitive command Passive command Translator Weakest preconditions A Hoare triple {P} S {Q} says that if command S is started in a state satisfying P, then S terminates without error in a state satisfying Q The weakest precondition of a command S with respect to a postcondition Q, written wp(S, Q), is the weakest P such that {P} S {Q}

Annotated Java program Verification condition Counterexample context Warning messages Automatic theorem prover Post processor Sugared command Primitive command Passive command Translator Weakest preconditions wp(assert E, Q) = E && Q wp(assume E, Q) = E ==> Q wp(S;T, Q) = wp(S, wp(T,Q)) wp(S [] T, Q) = wp(S, Q) && wp(T, Q) wp(x := E, Q) = Q[ x := E ]

private int scanPunctuation(int nextchr) { try { boolean possibleFloatingPointNumber = (nextchr == '.'); text[0] = (char)nextchr; textlen = 1; m_in.mark(); // All paths out of the try must unmark the stream!! PunctuationPrefixTree prefix = punctuationTable; PunctuationPrefixTree lastPunctuation = prefix; int lastPunctuationLength = 0; int index = nextchr - '!'; if (index < 0 || PunctuationPrefixTree.CHILDLEN <= index) prefix = null; else prefix = prefix.children[nextchr - '!']; nextchr = m_in.read(); if (possibleFloatingPointNumber && Character.isDigit((char)nextchr)) { m_in.clearMark(); return finishFloatingPointLiteral(nextchr); } this.append(nextchr); if (prefix != null && prefix.code != TagConstants.NULL) { lastPunctuation = prefix; lastPunctuationLength = textlen - 1; m_in.mark(); } while(prefix != null) { index = nextchr - '!'; if (index < 0 || PunctuationPrefixTree.CHILDLEN <= index) prefix = null; else prefix = prefix.children[nextchr - '!']; nextchr = m_in.read(); this.append(nextchr); if (prefix != null && prefix.code != TagConstants.NULL) { lastPunctuation = prefix; lastPunctuationLength = textlen - 1; m_in.mark(); } m_in.reset(); textlen = lastPunctuationLength; endingLoc = m_in.getLocation(); ttype = lastPunctuation.code; if (ttype != TagConstants.C_COMMENT&& ttype != TagConstants.EOL_COMMENT) nextchr = m_in.read(); return ttype; } catch (IOException e) { m_in.clearMark(); ErrorSet.fatal(m_in.getLocation(), e.toString()); return TagConstants.NULL; // Dummy }

Annotated Java program Verification condition Counterexample context Warning messages Automatic theorem prover Post processor Sugared command Primitive command Passive command Translator Verification condition Universal background predicate – (∀t ・ t <: t) Type-specific background predicate – Bag <: java.lang.Object Verification condition: BP Univ && BP T ==> VC method

(BG_PUSH (AND (<: T_T |T_java.lang.Object|) (EQ T_T (asChild T_T |T_java.lang.Object|)) (DISTINCT arrayType |T_boolean| |T_char| |T_byte| |T_short| |T_int| |T_long| |T_float| |T_double| |T_.TYPE| T_T |T_java.lang.Object|))) (EXPLIES (LBLNEG |vc.T.abs.2.2| (IMPLIES (AND (EQ elems) (EQ elems (asElems elems)) (< (eClosedTime elems) alloc) (EQ LS (asLockSet LS)) (EQ alloc)) (NOT (AND (EQ (is |x:2.21| T_int)) (OR (AND (OR (AND (< |x:2.21| 0) (LBLPOS |trace.Then^0,3.15| (EQ (EQ |x:3.17| (- 0 |x:2.21|)) (EQ |x:2.21 | |x:3.17|)) (AND (NOT (< |x:2.21| 0)) (LBLPOS |trace.Else^1,3.4| (EQ (EQ |x:2.21 | |x:2.21|))) (NOT (LBLNEG (>= |x:2.21 | 0)))) (AND (OR (AND (< |x:2.21| 0) (LBLPOS |trace.Then^0,3.15| (EQ (EQ |x:3.17| (- 0 |x:2.21|)) (EQ |x:2.21 | |x:3.17|)) (AND (NOT (< |x:2.21| 0)) (LBLPOS |trace.Else^1,3.4| (EQ (EQ |x:2.21 | |x:2.21|))) (LBLNEG (>= |x:2.21 | 0)) (NOT (LBLNEG (EQ |ecReturn| |ecReturn|))))))))) (AND (DISTINCT |ecReturn|))) Annotated Java program Verification condition Counterexample context Warning messages Automatic theorem prover Post processor Sugared command Primitive command Passive command Translator Verification condition class T { static int abs(int x) { if (x < 0) { x = -x; } assert x >= 0; }

Annotated Java program Verification condition Counterexample context Warning messages Automatic theorem prover Post processor Sugared command Primitive command Passive command Translator Theorem prover: “Simplify” Nelson-Oppen cooperating decision procedures – conguence closure – linear arithmetic – partial orders – quantifiers Key features: – automatic: no user interaction – refutation based: searches for counterexamples – heuristics tuned for program checking – labels – time limit

Annotated Java program Verification condition Counterexample context Warning messages Automatic theorem prover Post processor Sugared command Primitive command Passive command Translator Counterexamples and warnings Counterexample: labels: |vc.Bag.add.20.2| |trace.Then^0,21.23|) context: (AND (NEQ |tmp1!a:23.23| null) (NEQ this null) (EQ alloc) (EQ |tmp4!n:26.6| 0) … (<= alloc (vAllocTime |tmp3!a:26.4|)) ) Bag: add(int) Bag.java:26: Warning: Array index possibly too large (IndexTooBig) a[n] = x; ^ Execution trace information: Executed then branch in "Bag.java", line 21, col

Experience: annotations Capture common design decisions Suggested immediately by warnings Overhead: 4-10% of source code ~1 annotation per field or parameter Most common annotations: – non_null – container element types

Experience: performance 50% of all methods:< 0.5 s 80% of all methods:< 1 s time limit:300 s total time for Javafe (~40kloc): 65 min.

Related work ESC/Modula-3 Full functional specification and verification – JML, LOOP, B, Penelope,... Languages and language features – Euclid, Eiffel, Escher, Guava, Vault, Cqual,... – LCLint, refinement types, Types against races,... Other checking techniques – Abstract interpretation, PREfix, SLAM, Bandera, Java PathFinder 2, Canvas, ESP, AST Toolkit, Metal

Conclusions Using weakest precondition semantics and automatic decision procedures for program analysis works! Cost effective?

Reading Read Hudak’s paper on functional programming. Read at least the initial part of Pierce’s paper on foundational calculi (the part on lambda calculus).