The KeY Platform for Verification and Analysis of Java Programs - - PowerPoint PPT Presentation

the key platform for verification and analysis of java
SMART_READER_LITE
LIVE PREVIEW

The KeY Platform for Verification and Analysis of Java Programs - - PowerPoint PPT Presentation

The KeY Platform for Verification and Analysis of Java Programs Reiner H ahnle Technische Universit at Darmstadt Department of Computer Science, Software Engineering Group 25 April 2016 Joint Work with. . . Wolfgang Ahrendt, Bernhard


slide-1
SLIDE 1

The KeY Platform for Verification and Analysis of Java Programs

Reiner H¨ ahnle

Technische Universit¨ at Darmstadt Department of Computer Science, Software Engineering Group

25 April 2016

slide-2
SLIDE 2

Joint Work with. . .

Wolfgang Ahrendt, Bernhard Beckert, Richard Bubel, Christoph Gladisch, Daniel Grahl, Sarah Grebing, Martin Hentschel, Mihai Herda, Vladimir Klebanov, Wojciech Mostowski, Christoph Scheben, Peter H. Schmitt, Mattias Ulbrich, Nathan Wasser and many others over the last 12 years!

slide-3
SLIDE 3

The KeY Platform

slide-4
SLIDE 4

The KeY Platform

Target Languages

◮ sequential Java ◮ without floats, reflexion, lambdas

slide-5
SLIDE 5

The KeY Platform

Properties

◮ functional correctness ◮ framing ◮ information flow ◮ resource consumption

slide-6
SLIDE 6

The KeY Platform

Symbolic Execution Engine for Dynamic Logic

Threorem Proving Debugging Visualization Counter Examples Test Cases

slide-7
SLIDE 7

Deductive Verification of OO-Programs

The Ke Y Approach

Theorem Prover Proof Obligation Generator DL Formula

Specification Program File.java

?

slide-8
SLIDE 8

Deductive Verification of OO-Programs

The Ke Y Approach

Theorem Prover Proof Obligation Generator DL Formula

Specification Program File.java

?

slide-9
SLIDE 9

Formal Specification of OO Programs

Program Specification

Follows design-by-contract methodology

◮ Behavior of programs specified on level of classes and methods ◮ Contracts are used to specify methods

◮ precondition must be established by caller ◮ postcondition guaranteed by callee if precondition holds at

invocation time

◮ Invariants attached to classes to specify

◮ global system properties ◮ data consistency properties

slide-10
SLIDE 10

The Java Modeling Language (JML)

A Specification Language for Java

Sum and Maximum (VSComp 2010)

◮ Description: Given an N-element array of natural numbers,

write a program to compute the sum and the maximum of the elements in the array.

◮ Properties: Given that N ≥ 0 and a[i] ≥ 0 for 0 ≤ i < N,

prove the post-condition that sum ≤ N · max.

❝❧❛ss SumAndMax { ✐♥t sum; ✐♥t max; /*@ normal_behaviour @ r❡q✉✐r❡s (❭❢♦r❛❧❧ ✐♥t i; 0 <= i && i < a.length; 0 <= a[i]); @ ❛ss✐❣♥❛❜❧❡ sum, max; @ ❡♥s✉r❡s (❭❢♦r❛❧❧ ✐♥t i; 0 <= i && i < a.length; a[i] <= max); @ ❡♥s✉r❡s (❭❡①✐sts ✐♥t i; 0 <= i && i < a.length; max == a[i]); @ ❡♥s✉r❡s sum == (❭s✉♠ ✐♥t i; 0 <= i && i < a.length; a[i]); @ ❡♥s✉r❡s sum <= a.length * max; @*/ ✈♦✐❞ sumAndMax(✐♥t[] a) { ... } }

slide-11
SLIDE 11

Deductive Verification of OO-Programs

The Ke Y Approach

Theorem Prover Proof Obligation Generator DL Formula

Specification Program File.java

?

slide-12
SLIDE 12

Java Dynamic Logic

slide-13
SLIDE 13

Java Dynamic Logic

FOL ∃x.φ

slide-14
SLIDE 14

Java Dynamic Logic

Modal logic ∃x.♦φ

slide-15
SLIDE 15

Java Dynamic Logic

Multi-modal logic ∃x.♦∗♥φ

slide-16
SLIDE 16

Java Dynamic Logic

Dynamic logic ∃x.x < 0? y := −x ; x ≥ 0? y := x y ≥ 0

slide-17
SLIDE 17

Java Dynamic Logic

Java DL for (Integer i: c) y+= i*i; y ≥ 0

slide-18
SLIDE 18

Java Dynamic Logic

Java DL with updates ∃s : java.util.Set. {c := s} [for (Integer i: c) y+= i*i;] y ≥ 0

slide-19
SLIDE 19

Java Dynamic Logic

Java DL with updates ∃s : java.util.Set. {c := s} [for (Integer i: c) y+= i*i;] y ≥ 0 Relative partial correctness:

◮ Upφ: If program p is started in any state that validates U

and it terminates, then formula φ holds in the final state.

slide-20
SLIDE 20

Deductive Verification of OO-Programs

The Ke Y Approach

Theorem Prover Proof Obligation Generator DL Formula

Specification Program File.java

?

slide-21
SLIDE 21

Dynamic Logic Calculus

Analysis Technique: Sequent Calculus realizes symbolic interpreter

slide-22
SLIDE 22

Dynamic Logic Calculus

Analysis Technique: Sequent Calculus realizes symbolic interpreter

ifStatement

Γ, b . = true = ⇒ [p; rest]φ, ∆ Γ, b . = false = ⇒ [q; rest]φ, ∆ Γ = ⇒ [if (b) { p } else { q }; rest]φ, ∆

unwindLoop

Γ = ⇒ [ if(b) {p; while(b) p} rest]φ, ∆ Γ = ⇒ [ while(b) p rest]φ, ∆

slide-23
SLIDE 23

Symbolic Execution

public static int sum(int[] a) throws Exception { if (a == null) { throw new Exception(); } else { int sum = 0; for (int i = 0; i < a.length; i++) { sum += a[i]; } return sum; } }

slide-24
SLIDE 24

Symbolic Execution

if (a == null) a: a0 public static int sum(int[] a) throws Exception { if (a == null) { throw new Exception(); } else { int sum = 0; for (int i = 0; i < a.length; i++) { sum += a[i]; } return sum; } }

slide-25
SLIDE 25

Symbolic Execution

if (a == null) a: a0 throw new Exception(); a: a0 {a0 = null} a0 = null public static int sum(int[] a) throws Exception { if (a == null) { throw new Exception(); } else { int sum = 0; for (int i = 0; i < a.length; i++) { sum += a[i]; } return sum; } }

slide-26
SLIDE 26

Symbolic Execution

if (a == null) a: a0 throw new Exception(); a: a0 {a0 = null} int sum = 0; a: a0 {a0 ≠ null} a0 = null a0 ≠ null public static int sum(int[] a) throws Exception { if (a == null) { throw new Exception(); } else { int sum = 0; for (int i = 0; i < a.length; i++) { sum += a[i]; } return sum; } }

slide-27
SLIDE 27

Symbolic Execution

if (a == null) a: a0 throw new Exception(); a: a0 {a0 = null} int sum = 0; a: a0 {a0 ≠ null} int i = 0; sum: 0 a0 = null a0 ≠ null public static int sum(int[] a) throws Exception { if (a == null) { throw new Exception(); } else { int sum = 0; for (int i = 0; i < a.length; i++) { sum += a[i]; } return sum; } }

slide-28
SLIDE 28

Symbolic Execution

if (a == null) a: a0 throw new Exception(); a: a0 {a0 = null} int sum = 0; a: a0 {a0 ≠ null} int i = 0; sum: 0 i < a.length; i: 0 a0 = null a0 ≠ null public static int sum(int[] a) throws Exception { if (a == null) { throw new Exception(); } else { int sum = 0; for (int i = 0; i < a.length; i++) { sum += a[i]; } return sum; } }

slide-29
SLIDE 29

Symbolic Execution

if (a == null) a: a0 throw new Exception(); a: a0 {a0 = null} int sum = 0; a: a0 {a0 ≠ null} int i = 0; sum: 0 i < a.length; i: 0 return sum; a.length: 0 a0 = null a0 ≠ null a0.length = 0 public static int sum(int[] a) throws Exception { if (a == null) { throw new Exception(); } else { int sum = 0; for (int i = 0; i < a.length; i++) { sum += a[i]; } return sum; } }

slide-30
SLIDE 30

Symbolic Execution

if (a == null) a: a0 throw new Exception(); a: a0 {a0 = null} int sum = 0; a: a0 {a0 ≠ null} int i = 0; sum: 0 i < a.length; i: 0 return sum; a.length: 0 a0 = null a0 ≠ null a0.length = 0 a0.length > 0 sum += a[i]; a.length: len0 {len0 > 0} public static int sum(int[] a) throws Exception { if (a == null) { throw new Exception(); } else { int sum = 0; for (int i = 0; i < a.length; i++) { sum += a[i]; } return sum; } }

slide-31
SLIDE 31

Symbolic Execution

public static int sum(int[] a) throws Exception { if (a == null) { throw new Exception(); } else { int sum = 0; for (int i = 0; i < a.length; i++) { sum += a[i]; } return sum; } } sum += a[i]; a: a0 {a0 ≠ null} a.length: len0 {len0 > 0} i: 0 sum: 0

slide-32
SLIDE 32

Symbolic Execution

public static int sum(int[] a) throws Exception { if (a == null) { throw new Exception(); } else { int sum = 0; for (int i = 0; i < a.length; i++) { sum += a[i]; } return sum; } } i++; sum: a0[0] sum += a[i]; a: a0 {a0 ≠ null} a.length: len0 {len0 > 0} i: 0 sum: 0

slide-33
SLIDE 33

Symbolic Execution

public static int sum(int[] a) throws Exception { if (a == null) { throw new Exception(); } else { int sum = 0; for (int i = 0; i < a.length; i++) { sum += a[i]; } return sum; } } i++; sum: a0[0] i < a.length; i: 1 sum += a[i]; a: a0 {a0 ≠ null} a.length: len0 {len0 > 0} i: 0 sum: 0

slide-34
SLIDE 34

Symbolic Execution

public static int sum(int[] a) throws Exception { if (a == null) { throw new Exception(); } else { int sum = 0; for (int i = 0; i < a.length; i++) { sum += a[i]; } return sum; } } i++; sum: a0[0] i < a.length; i: 1 return sum; a.length: 1 a0.length = 1 sum += a[i]; a: a0 {a0 ≠ null} a.length: len0 {len0 > 0} i: 0 sum: 0

slide-35
SLIDE 35

Symbolic Execution

public static int sum(int[] a) throws Exception { if (a == null) { throw new Exception(); } else { int sum = 0; for (int i = 0; i < a.length; i++) { sum += a[i]; } return sum; } } i++; sum: a0[0] i < a.length; i: 1 return sum; a.length: 1 sum += a[i]; a.length: len0 {len0 > 1} a0.length = 1 a0.length > 1 sum += a[i]; a: a0 {a0 ≠ null} a.length: len0 {len0 > 0} i: 0 sum: 0

slide-36
SLIDE 36

Symbolic Execution

public static int sum(int[] a) throws Exception { if (a == null) { throw new Exception(); } else { int sum = 0; for (int i = 0; i < a.length; i++) { sum += a[i]; } return sum; } } i++; sum: a0[0] i < a.length; i: 1 return sum; a.length: 1 sum += a[i]; a.length: len0 {len0 > 1} a0.length = 1 a0.length > 1 sum += a[i]; a: a0 {a0 ≠ null} a.length: len0 {len0 > 0} i: 0 sum: 0

slide-37
SLIDE 37

Dynamic Logic Calculus

Analysis Technique: Sequent Calculus realizes symbolic interpreter

ifStatement

Γ, b . = true = ⇒ [p; rest]φ, ∆ Γ, b . = false = ⇒ [q; rest]φ, ∆ Γ = ⇒ [if (b) { p } else { q }; rest]φ, ∆

unwindLoop

Γ = ⇒ [ if(b) {p; while(b) p} rest]φ, ∆ Γ = ⇒ [ while(b) p rest]φ, ∆ How to achieve finite proof tree for unbounded loops?

slide-38
SLIDE 38

Dynamic Logic Calculus

Analysis Technique: Sequent Calculus realizes symbolic interpreter

ifStatement

Γ, b . = true = ⇒ [p; rest]φ, ∆ Γ, b . = false = ⇒ [q; rest]φ, ∆ Γ = ⇒ [if (b) { p } else { q }; rest]φ, ∆

unwindLoop

Γ = ⇒ [ if(b) {p; while(b) p} rest]φ, ∆ Γ = ⇒ [ while(b) p rest]φ, ∆ How to achieve finite proof tree for unbounded loops? loopInvariant Γ = ⇒ Inv, ∆ (initially valid) Inv, b . = true = ⇒ [p]Inv (preserved) Inv, b . = false = ⇒ [rest]φ (use case) Γ = ⇒ [ while(b){ p } rest]φ, ∆

slide-39
SLIDE 39

TOOL DEMO

slide-40
SLIDE 40

Standard Libraries: A Worthwhile Application Scenario

Deductive verification for general behavioral properties of “algorithmic challenging” programs requires

◮ interactions, and is hence, ◮ time (and cost) expensive

st❛t✐❝ ✈♦✐❞ ✐♥t st❛t✐❝ ✐♥t ✐♥t ✐♥t

slide-41
SLIDE 41

Standard Libraries: A Worthwhile Application Scenario

Deductive verification for general behavioral properties of “algorithmic challenging” programs requires

◮ interactions, and is hence, ◮ time (and cost) expensive

Correctness of library functions is crucial: used in millions of programs

Java standard library functions

◮ Sorting a given array a

st❛t✐❝ ✈♦✐❞ sort(✐♥t[] a)

◮ Search a value key in the array a

st❛t✐❝ ✐♥t binarySearch(✐♥t[] a, ✐♥t key)

slide-42
SLIDE 42

Timsort

Description

Timsort: a hybrid sorting algorithm (insertion sort + merge sort)

  • ptimized for partially sorted arrays (typical in real-world data)
slide-43
SLIDE 43

Timsort

Description

Timsort: a hybrid sorting algorithm (insertion sort + merge sort)

  • ptimized for partially sorted arrays (typical in real-world data)

Facts

◮ Designed by Tim Peters (for Python) ◮ Since Java 7 default algorithm for non-primitive arrays

slide-44
SLIDE 44

Timsort

Description

Timsort: a hybrid sorting algorithm (insertion sort + merge sort)

  • ptimized for partially sorted arrays (typical in real-world data)

Facts

◮ Designed by Tim Peters (for Python) ◮ Since Java 7 default algorithm for non-primitive arrays

Timsort is used in

◮ Java (standard library) ◮ Python (standard library) ◮ Android (standard library) ◮ ... and many more languages / frameworks!

slide-45
SLIDE 45

Timsort

Description

Timsort: a hybrid sorting algorithm (insertion sort + merge sort)

  • ptimized for partially sorted arrays (typical in real-world data)

Facts

◮ Designed by Tim Peters (for Python) ◮ Since Java 7 default algorithm for non-primitive arrays

Timsort is used in

◮ Java (standard library) ◮ Python (standard library) ◮ Android (standard library) ◮ ... and many more languages / frameworks! Exception in thread "main" ArrayIndexOutOfBoundsException: 40 at java.util.TimSort.pushRun(TimSort.java:386) at java.util.TimSort.sort(TimSort.java:213) at java.util.Arrays.sort(Arrays.java:659) at TestTimSort.main(TestTimSort.java:18)

slide-46
SLIDE 46

Fixing and Verifying TimSort

◮ Add a test to one method (mergeCollapse) to ensure that

invariant holds

◮ Formally specify the invariant as class invariant ◮ Specify contracts for all methods ◮ Specify loop invariants ◮ Verify that each method

◮ satisfies its contract ◮ preserves the class invariant

slide-47
SLIDE 47

Verification Effort

◮ Adding support for bitwise operations to KeY ◮ Adding capability to merge symbolic execution nodes ◮ 460 lines of specification vs. 928 lines of code ◮ Fixed version formally verified (in contrast to previous ”fixes”) ◮ Not yet proven:

◮ sortedness & permutation

◮ Effort

◮ ca. 3 Mio. rule applications ◮ ca. 5,000 interactions

slide-48
SLIDE 48

Aftermath

◮ Java community fixed the bug by increasing stack size

(based on pen-and-paper worst case analysis)

slide-49
SLIDE 49

Aftermath

◮ Java community fixed the bug by increasing stack size

(based on pen-and-paper worst case analysis)

◮ Android community provided their own fix

(which we proved in the meantime as well)

slide-50
SLIDE 50

Aftermath

◮ Java community fixed the bug by increasing stack size

(based on pen-and-paper worst case analysis)

◮ Android community provided their own fix

(which we proved in the meantime as well)

◮ Python community adopted our formally proven fix

slide-51
SLIDE 51

Aftermath

◮ Java community fixed the bug by increasing stack size

(based on pen-and-paper worst case analysis)

◮ Android community provided their own fix

(which we proved in the meantime as well)

◮ Python community adopted our formally proven fix ◮ Bug affected

◮ Java, Android, Python ◮ Apache: Lucene, Hadoop, Spark++ ◮ Go, D, Haskell

Language

  • Min. array length req. to trigger error

Android 65.536 (216) Java 67.108.864 (226) Python 562.949.953.421.312 (249)

slide-52
SLIDE 52

Aftermath

◮ Java community fixed the bug by increasing stack size

(based on pen-and-paper worst case analysis)

◮ Android community provided their own fix

(which we proved in the meantime as well)

◮ Python community adopted our formally proven fix ◮ Bug affected

◮ Java, Android, Python ◮ Apache: Lucene, Hadoop, Spark++ ◮ Go, D, Haskell

Language

  • Min. array length req. to trigger error

Android 65.536 (216) Java 67.108.864 (226) Python 562.949.953.421.312 (249)

◮ Formal verification works for ”real” languages! ◮ Hundreds of thousands page views, top news on ycombinator,

reddit, Hacker News etc.

slide-53
SLIDE 53

Aftermath

◮ Java community fixed the bug by increasing stack size

(based on pen-and-paper worst case analysis)

◮ Android community provided their own fix

(which we proved in the meantime as well)

◮ Python community adopted our formally proven fix ◮ Bug affected

◮ Java, Android, Python ◮ Apache: Lucene, Hadoop, Spark++ ◮ Go, D, Haskell

Language

  • Min. array length req. to trigger error

Android 65.536 (216) Java 67.108.864 (226) Python 562.949.953.421.312 (249)

◮ Formal verification works for ”real” languages! ◮ Hundreds of thousands page views, top news on ycombinator,

reddit, Hacker News etc. W e l l , w

  • u

l d y

  • u

l

  • k

a t t h a t . K e Y i s a c

  • t

u a l l y u s e d f

  • r

s

  • m

e t h i n g u s e f u l . I t h

  • u

g h t t h e y j u s t t

  • r

t u r e d u s w i t h i t f

  • r

f u n a t u n i

  • v

e r s i t y . U n k n

  • w

n s t u d e n t v i a r e d d i t

slide-54
SLIDE 54

Aftermath

◮ Java community fixed the bug by increasing stack size

(based on pen-and-paper worst case analysis)

◮ Android community provided their own fix

(which we proved in the meantime as well)

◮ Python community adopted our formally proven fix ◮ Bug affected

◮ Java, Android, Python ◮ Apache: Lucene, Hadoop, Spark++ ◮ Go, D, Haskell

Language

  • Min. array length req. to trigger error

Android 65.536 (216) Java 67.108.864 (226) Python 562.949.953.421.312 (249)

◮ Formal verification works for ”real” languages! ◮ Hundreds of thousands page views, top news on ycombinator,

reddit, Hacker News etc. W e l l , w

  • u

l d y

  • u

l

  • k

a t t h a t . K e Y i s a c

  • t

u a l l y u s e d f

  • r

s

  • m

e t h i n g u s e f u l . I t h

  • u

g h t t h e y j u s t t

  • r

t u r e d u s w i t h i t f

  • r

f u n a t u n i

  • v

e r s i t y . U n k n

  • w

n s t u d e n t v i a r e d d i t Some researchers found an error in the logic of merge collapse, explained here, and with corrected code shown in . . . It should be fixed anyway, and their sug- gested fix looks good to me. Tim Peters via Python-Bugtracker

slide-55
SLIDE 55

Aftermath

◮ Java community fixed the bug by increasing stack size

(based on pen-and-paper worst case analysis)

◮ Android community provided their own fix

(which we proved in the meantime as well)

◮ Python community adopted our formally proven fix ◮ Bug affected

◮ Java, Android, Python ◮ Apache: Lucene, Hadoop, Spark++ ◮ Go, D, Haskell

Language

  • Min. array length req. to trigger error

Android 65.536 (216) Java 67.108.864 (226) Python 562.949.953.421.312 (249)

◮ Formal verification works for ”real” languages! ◮ Hundreds of thousands page views, top news on ycombinator,

reddit, Hacker News etc. W e l l , w

  • u

l d y

  • u

l

  • k

a t t h a t . K e Y i s a c

  • t

u a l l y u s e d f

  • r

s

  • m

e t h i n g u s e f u l . I t h

  • u

g h t t h e y j u s t t

  • r

t u r e d u s w i t h i t f

  • r

f u n a t u n i

  • v

e r s i t y . U n k n

  • w

n s t u d e n t v i a r e d d i t Some researchers found an error in the logic of merge collapse, explained here, and with corrected code shown in . . . It should be fixed anyway, and their sug- gested fix looks good to me. Tim Peters via Python-Bugtracker Congratulations to Stijn de Gouw et al. for finding and fixing a bug in TimSort using formal methods! Joshua Bloch via Twitter