extended static checking for java
Download
Skip this Video
Download Presentation
Extended Static Checking for Java

Loading in 2 Seconds...

play fullscreen
1 / 38

Extended Static Checking for Java - PowerPoint PPT Presentation


  • 148 Views
  • Uploaded on

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.

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'Extended Static Checking for Java' - panthea


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
extended static checking for java

Extended Static Checkingfor Java

Cormac Flanagan

Slides courtesy of Rustan Leino

software development problem
Software development problem
  • Software construction and maintenance are expensive
  • Reliability is costly and difficult to achieve
vision
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
User\'s view

Error messages

Program with specifications

Program checker

public class Bag {

private /*@non_null*/ int[] a; private int n; //@ invariant 0 <= n && n <= a.length;

public Bag(/*@non_null*/ 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
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
weakest preconditions in practice
Weakest Preconditions in Practice
  • Given procedure

//@ requires Pre

//@ ensures Post

procedure m() { c } // c is an IMP command

  • Generate verification condition

Pre => WP( c, Post )

  • Check this VC is valid (true in all states)
    • If so, then any execution of m() from a Pre–state is guaranteed to terminate only in Post–states.
  • Use automatic theorem proving to check VC
  • Performs modular checking, requires annotations
program checker design tradeoffs
Program checker design tradeoffs
  • Missed errors
  • Spurious warnings
  • Annotation overhead
  • Performance
esc java architecture
ESC/Java architecture

Annotated Java program

Translator

Verification condition

Valid

Automatic theorem prover

Resource exhausted

Counterexample context

Post processor

Warning messages

tool architecture detail
Tool architecture, detail

Annotated Java program

Sugared command

Translator

Primitive command

Passive command

Verification condition

Automatic theorem prover

Counterexample context

Post processor

Warning messages

tool architecture detail12

Annotated Java program

Annotated Java program

Sugared command

Sugared command

Primitive command

Translator

Translator

Primitive command

Passive command

Passive command

Verification condition

Verification condition

Automatictheorem prover

Automatic theorem prover

Counterexample context

Counterexample context

Post processor

Post processor

Warning messages

Warning messages

Tool architecture, detail
annotation language
Annotation language

Annotated Java program

  • Simple
    • non_null
  • Method annotations
    • requires E;
    • ensures E;
    • exsures (T x) E;
    • modifies w;
  • Object invariants
    • invariantE;

Sugared command

Primitive command

Translator

Passive command

Verification condition

Automatictheorem prover

Counterexample context

Post processor

Warning messages

annotation language14
Annotation language

Annotated Java program

  • Simple
    • non_null
  • Method annotations
    • requires E;
    • modifies w;
    • ensures E;
    • exsures (T x) E;
  • Object invariants
    • invariantE;

Sugared command

Primitive command

Translator

Passive command

Verification condition

Automatictheorem prover

Counterexample context

Post processor

Warning messages

annotation language15
Annotation language

Annotated Java program

  • Specification expressions
    • side-effect free Java expressions
      • no ++, no method calls
    • result
      • ensuresresult >= 0;
    • old(E)
      • ensuresx == old(x)+1;
    • (forall T x; E), (exists T x; E), ==>
      • (forallint j; 0 <= j && j < n ==> a[j] > 0);

Sugared command

Primitive command

Translator

Passive command

Verification condition

Automatictheorem prover

Counterexample context

Post processor

Warning messages

annotation language16
Annotation language

Annotated Java program

  • Specification expressions
    • side-effect free Java expressions
      • no ++, no method calls
    • result
      • ensuresresult >= 0;
    • old(E)
      • ensuresx == old(x)+1;
    • (forall T x; E), (exists T x; E), ==>
      • (forallint j; 0 <= j && j < n ==> a[j] > 0);

Sugared command

Primitive command

Translator

Passive command

Verification condition

Automatictheorem prover

Counterexample context

Post processor

Warning messages

annotation language17
Annotation language

Annotated Java program

  • Miscellaneous
    • assert E;
    • assume E;
      • assume x >= 0; // because x == y*y
    • nowarn
      • x = a[j]; //@ nowarn
    • axiom E;
      • axiom (forallint x; x ≫ 2 >= 0);
  • Concurrency, ghost variables

Sugared command

Primitive command

Translator

Passive command

Verification condition

Automatictheorem prover

Counterexample context

Post processor

Warning messages

sugared commands
Sugared commands

Annotated Java program

  • 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)

| …

Sugared command

Primitive command

Translator

Passive command

Verification condition

Automatictheorem prover

Counterexample context

Post processor

Warning messages

sugared commands19
Sugared commands

Annotated Java program

  • x = t.f.g;

assert t ≠ null;

tmp = select(f, t);

assert tmp ≠ null;

x = select(g, tmp)

  • if (x < 0) { x = -x; }/*@ assert x >= 0; */

( assume x < 0; x = -x

[] assume¬(x < 0)

);

assert x >= 0

Sugared command

Primitive command

Translator

Passive command

Verification condition

Automatictheorem prover

Counterexample context

Post processor

Warning messages

sugared commands20
Sugared commands

Annotated Java program

  • x = t.f.g;

assert lblneg(“[email protected]”, t ≠ null);

tmp = select(f, t);

assert lblneg(“[email protected]”, tmp ≠ null);

x = select(g, tmp)

  • if (x < 0) { x = -x; }/*@ assert 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

Sugared command

Primitive command

Translator

Passive command

Verification condition

Automatictheorem prover

Counterexample context

Post processor

Warning messages

primitive commands
Primitive commands

Annotated Java program

  • 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)

| …

Sugared command

Primitive command

Translator

Passive command

Verification condition

Automatictheorem prover

Counterexample context

Post processor

Warning messages

primitive commands22
Primitive commands

Annotated Java program

  • //@ requires Pre; modifies w; ensures Post;void m(U u);
  • call x = m(E)

var u in

u = E;

assert Pre;

var w0in

w0 = w;

havoc w;

assume Post;

x = result

end

end

Sugared command

Primitive command

Translator

Passive command

Verification condition

Automatictheorem prover

Counterexample context

Post processor

Warning messages

passive commands

| raise

| S ; T

| S ! T

| S [] T

Passive commands

Annotated Java program

  • S,T ::= assert E

| assume E

| x = E

Sugared command

Primitive command

Translator

Passive command

Verification condition

Automatictheorem prover

Counterexample context

Post processor

Warning messages

slide24

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

}

}

passive commands25
Passive commands

Annotated Java program

  • if (x < 0) { x= -x; }/*@ assert x >= 0; */

( assume x0 < 0; x1 = -x0;x2 = x1

[] assume ¬(x0 < 0);x2 = x0

);

assert x2 >= 0

Sugared command

Primitive command

Translator

Passive command

Verification condition

Automatictheorem prover

Counterexample context

Post processor

Warning messages

passive commands26
Passive commands

Annotated Java program

  • if (x < 0) { x= -x; }/*@ assert x >= 0; */

( assume x0 < 0; assume x1 == -x0;assume x2 == x1

[] assume ¬(x0 < 0);assume x2 == x0

);

assert x2 >= 0

Sugared command

Primitive command

Translator

Passive command

Verification condition

Automatictheorem prover

Counterexample context

Post processor

Warning messages

weakest preconditions
Weakest preconditions

Annotated Java program

  • 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}

Sugared command

Primitive command

Translator

Passive command

Verification condition

Automatictheorem prover

Counterexample context

Post processor

Warning messages

weakest preconditions28
Weakest preconditions

Annotated Java program

  • 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 ]

Sugared command

Primitive command

Translator

Passive command

Verification condition

Automatictheorem prover

Counterexample context

Post processor

Warning messages

slide29

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

}

}

verification condition
Verification condition

Annotated Java program

  • Universal background predicate
    • (∀t ・ t <: t)
  • Type-specific background predicate
    • Bag <: java.lang.Object
  • Verification condition:BPUniv && BPT ==> VCmethod

Sugared command

Primitive command

Translator

Passive command

Verification condition

Automatictheorem prover

Counterexample context

Post processor

Warning messages

verification condition31

(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 |[email protected]| elems)

(EQ elems (asElems elems))

(< (eClosedTime elems) alloc)

(EQ LS (asLockSet LS))

(EQ |[email protected]| alloc))

(NOT

(AND

(EQ |@true| (is |x:2.21| T_int))

(OR

(AND

(OR

(AND

(< |x:2.21| 0)

(LBLPOS |trace.Then^0,3.15| (EQ |@true| |@true|))

(EQ |x:3.17| (- 0 |x:2.21|))

(EQ |x:2.21<1>| |x:3.17|))

(AND

(NOT (< |x:2.21| 0))

(LBLPOS |trace.Else^1,3.4| (EQ |@true| |@true|))

(EQ |x:2.21<1>| |x:2.21|)))

(NOT (LBLNEG |[email protected]| (>= |x:2.21<1>| 0))))

(AND

(OR

(AND

(< |x:2.21| 0)

(LBLPOS |trace.Then^0,3.15| (EQ |@true| |@true|))

(EQ |x:3.17| (- 0 |x:2.21|))

(EQ |x:2.21<1>| |x:3.17|))

(AND

(NOT (< |x:2.21| 0))

(LBLPOS |trace.Else^1,3.4| (EQ |@true| |@true|))

(EQ |x:2.21<1>| |x:2.21|)))

(LBLNEG |[email protected]| (>= |x:2.21<1>| 0))

(NOT (LBLNEG |[email protected]| (EQ |ecReturn| |ecReturn|)))))))))

(AND

(DISTINCT |ecReturn|)))

Verification condition

Annotated Java program

  • class T {

staticint abs(int x) {

if (x < 0) { x = -x; }

//@ assert x >= 0;

}

}

Sugared command

Primitive command

Translator

Passive command

Verification condition

Automatictheorem prover

Counterexample context

Post processor

Warning messages

theorem prover simplify
Theorem prover: “Simplify”

Annotated Java program

  • 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

Sugared command

Primitive command

Translator

Passive command

Verification condition

Automatictheorem prover

Counterexample context

Post processor

Warning messages

counterexamples and warnings
Counterexamples and warnings

Annotated Java program

  • Counterexample: labels: (|[email protected]| |vc.Bag.add.20.2| |trace.Then^0,21.23|) context: (AND (NEQ |tmp1!a:23.23| null) (NEQ this null) (EQ |[email protected]| 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 23.-----------------------------------------------------------

Sugared command

Primitive command

Translator

Passive command

Verification condition

Automatictheorem prover

Counterexample context

Post processor

Warning messages

experience annotations
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
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
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
Conclusions
  • Using weakest precondition semantics and automatic decision procedures for program analysis works!
  • Cost effective?
reading
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).
ad