Top Banner
Software Verification with BLAST Tom Henzinger Ranjit Jhala Rupak Majumdar
132

Software Verification with BLAST

Jan 22, 2016

Download

Documents

Shane Gallagher

Software Verification with BLAST. Tom Henzinger Ranjit Jhala Rupak Majumdar. Blast Web Site. http://www.eecs.berkeley.edu/~blast. Software Validation. Large scale reliable software is hard to build and test Different groups write different components Integration testing is a nightmare. - PowerPoint PPT Presentation
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Software Verification with BLAST

Software Verification withBLAST

Tom Henzinger Ranjit Jhala Rupak Majumdar

Page 2: Software Verification with BLAST

Blast Web Site

http://www.eecs.berkeley.edu/~blast

Page 3: Software Verification with BLAST

Software Validation

• Large scale reliable software is hard to build and test

• Different groups write different components

• Integration testing is a nightmare

Page 4: Software Verification with BLAST

Property Checking

• Programmer gives partial specifications

• Code checked for consistency w/ spec

• Different from program correctness – Specifications are not complete– Is there a complete spec for Word ?

Emacs ?

Page 5: Software Verification with BLAST

Interface Usage Rules

• Rules in documentation–Order of operations & data access–Resource management –Incomplete, unenforced, wordy

• Violated rules ) bad behavior–System crash or deadlock–Unexpected exceptions–Failed runtime checks

Page 6: Software Verification with BLAST

Property 1: Double Locking

“An attempt to re-acquire an acquired lock or release a released lock will cause a deadlock.”

Calls to lock and unlock must alternate.

lock

lock

unlock

unlock

Page 7: Software Verification with BLAST

Property 2: Drop Root Privilege

“User applications must not run with root privilege”

When execv is called, must have suid 0

[Chen-Dean-Wagner ’02]

Page 8: Software Verification with BLAST

Property 3 : IRP Handler

[Fahndrich]

MPR3

CallDriver

MPRcompletion

synch

not pending returned

SKIP2

IPCCallDriverSkip

returnchild status

DC

Completerequest return

not Pend

PPCprop

completion

CallDriver

N/A

no propcompletion CallDriver

start NP

returnPending

NP

MPR1

MPRcompletion

SKIP2

IPCCallDriver

CallDriver

DC

Completerequest

PPCprop

completion

CallDriver

N/A

no propcompletion CallDriver

start P Mark Pending

IRP accessible N/A

synch

SKIP1CallDriver

SKIP1Skip

MPR2 MPR1

NP

MPR3

CallDrivernot pending returned

MPR2

synch

Page 9: Software Verification with BLAST

Does a given usage rule hold?• Undecidable!

– Equivalent to the halting problem

• Restricted computable versions are prohibitively expensive (PSPACE)

• Why bother ?– Just because a problem is undecidable, it doesn’t go away!

Page 10: Software Verification with BLAST

Plan

• Motivation• Lazy Abstraction• Demo• Technical Details

Page 11: Software Verification with BLAST

Example

Example ( ) {1: do{ lock(); old = new;

q = q->next;2: if (q != NULL){3: q->data = new;

unlock(); new ++; }4: } while(new != old);5: unlock (); return;}

Example ( ) {1: do{ lock(); old = new;

q = q->next;2: if (q != NULL){3: q->data = new;

unlock(); new ++; }4: } while(new != old);5: unlock (); return;}

lock

lock

unlock

unlock

Page 12: Software Verification with BLAST

What a program really is…

StateTransition

3: unlock(); new++;4:} …

3: unlock(); new++;4:} …

pclockoldnewq

3 5 5 0x133a

pclockoldnewq

4 5 6 0x133a

Example ( ) {1: do{ lock(); old = new;

q = q->next;2: if (q != NULL){3: q->data = new;

unlock(); new ++; }4: } while(new != old);5: unlock (); return;}

Example ( ) {1: do{ lock(); old = new;

q = q->next;2: if (q != NULL){3: q->data = new;

unlock(); new ++; }4: } while(new != old);5: unlock (); return;}

Page 13: Software Verification with BLAST

The Safety Verification Problem

Initial

Error

Is there a path from an initial to an error state ?Problem: Infinite state graphSolution : Set of states ' logical formula

Safe

Page 14: Software Verification with BLAST

Representing States as Formulas

[F]states satisfying F {s | s ² F }

FFO fmla over prog. vars

[F1] Å [F2] F1 Æ F2

[F1] [ [F2] F1 Ç F2

[F] : F

[F1] µ [F2] F1 implies F2

i.e. F1Æ: F2 unsatisfiable

Page 15: Software Verification with BLAST

Idea 1: Predicate Abstraction

• Predicates on program state:lockold = new

• States satisfying same predicatesare equivalent– Merged into one abstract state

• #abstract states is finite

Page 16: Software Verification with BLAST

Abstract States and Transitions

State

3: unlock(); new++;4:} …

3: unlock(); new++;4:} …

pclockoldnewq

3 5 5 0x133a

pclockoldnewq

4 5 6 0x133a

lock old=new

: lock : old=new

Theorem Prover

Page 17: Software Verification with BLAST

Abstraction

State

3: unlock(); new++;4:} …

3: unlock(); new++;4:} …

pclockoldnewq

3 5 5 0x133a

pclockoldnewq

4 5 6 0x133a

lock old=new

: lock : old=new

Theorem Prover

Existential Lifting

Page 18: Software Verification with BLAST

Abstraction

State

3: unlock(); new++;4:} …

3: unlock(); new++;4:} …

pclockoldnewq

3 5 5 0x133a

pclockoldnewq

4 5 6 0x133a

lock old=new

: lock : old=new

Page 19: Software Verification with BLAST

Analyze Abstraction

Analyze finite graph

Over Approximate: Safe ) System Safe

No false negatives

ProblemSpurious

counterexamples

Page 20: Software Verification with BLAST

Idea 2: Counterex.-Guided Refinement

SolutionUse spurious

counterexamplesto refine abstraction !

Page 21: Software Verification with BLAST

1. Add predicates to distinguish

states across cut2. Build refined abstraction

SolutionUse spurious

counterexamplesto refine abstraction

Idea 2: Counterex.-Guided Refinement

Imprecision due to merge

Page 22: Software Verification with BLAST

Iterative Abstraction-Refinement

1. Add predicates to distinguish states across cut2. Build refined abstraction

-eliminates counterexample

3. Repeat searchTill real counterexampleor system proved safe

SolutionUse spurious

counterexamplesto refine abstraction

[Kurshan et al 93] [Clarke et al 00][Ball-Rajamani 01]

Page 23: Software Verification with BLAST

Lazy Abstraction

Abstract

Refine

C Program

Safe

Trace

Yes

NoPropert

y

BLAST

Page 24: Software Verification with BLAST

Lazy Abstraction

C Program

Safe

Trace

Yes

NoProperty

BLASTspec.opt

InstrumentedC file

With ERRORlabel

Page 25: Software Verification with BLAST

Problem: Abstraction is Expensive

Reachable

Problem#abstract states = 2#predicates

Exponential Thm. Prover queries

ObserveFraction of state space reachable#Preds ~ 100’s, #States ~ 2100 ,#Reach ~ 1000’s

Page 26: Software Verification with BLAST

Safe

SolutionBuild abstraction during search

Problem#abstract states = 2#predicates

Exponential Thm. Prover queries

Solution1: Only Abstract Reachable States

Page 27: Software Verification with BLAST

SolutionDon’t refine error-free regions

Problem#abstract states = 2#predicates

Exponential Thm. Prover queries

Solution2: Don’t Refine Error-Free Regions

Error Free

Page 28: Software Verification with BLAST

Key Idea: Reachability Tree

5

1

2

3

4

3

Unroll Abstraction1. Pick tree-node (=abs. state)2. Add children (=abs. successors)3. On re-visiting abs. state, cut-off

Find min infeasible suffix

- Learn new predicates- Rebuild subtree with new preds.

Initial

Page 29: Software Verification with BLAST

Key Idea: Reachability Tree

3

1

2

3

4 5

3

7

6

Error Free

Unroll Abstraction1. Pick tree-node (=abs. state)2. Add children (=abs. successors)3. On re-visiting abs. state, cut-off

Find min infeasible suffix

- Learn new predicates- Rebuild subtree with new preds.

Initial

Page 30: Software Verification with BLAST

Key Idea: Reachability Tree

3

1

2

3

4 5

3

6

Error Free

7

1

8

8 1

SAFE

Unroll1. Pick tree-node (=abs. state)2. Add children (=abs. successors)3. On re-visiting abs. state, cut-off

Find min spurious suffix

- Learn new predicates- Rebuild subtree with new preds.

S1: Only Abstract Reachable States

S2: Don’t refine error-free regions

Initial

Page 31: Software Verification with BLAST

Build-and-Search

Predicates: LOCK

: LOCK

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

1

1

Reachability Tree

Page 32: Software Verification with BLAST

Build-and-Search

Predicates: LOCK

: LOCK

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

1

1

lock()

old = new

q=q->next LOCK2

2

Reachability Tree

Page 33: Software Verification with BLAST

Build-and-Search

Predicates: LOCK

: LOCK

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

1

1

LOCK2

2

LOCK

[q!=NULL]

3

3

Reachability Tree

Page 34: Software Verification with BLAST

Build-and-Search

Predicates: LOCK

: LOCK

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

1

1

LOCK2

2

LOCK3

3

q->data = new

unlock()

new++ 4

4

: LOCK

Reachability Tree

Page 35: Software Verification with BLAST

Build-and-Search

Predicates: LOCK

: LOCK

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

1

1

LOCK2

2

LOCK3

3

4

4

: LOCK

: LOCK

[new==old]

55

Reachability Tree

Page 36: Software Verification with BLAST

Build-and-Search

Predicates: LOCK

: LOCK

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

1

1

LOCK2

2

LOCK3

3

4

4

: LOCK

: LOCK55

unlock()

: LOCK

Reachability Tree

Page 37: Software Verification with BLAST

Analyze Counterexample

Predicates: LOCK

: LOCK

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

1

1

LOCK2

2

LOCK3

3

4

4

: LOCK

: LOCK55

: LOCK

Reachability Tree

lock()

old = new

q=q->next

[q!=NULL]

q->data = new

unlock()

new++

[new==old]

unlock()

Page 38: Software Verification with BLAST

Analyze Counterexample

Predicates: LOCK

: LOCK

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

1

1

LOCK2

2

LOCK3

3

4

4

: LOCK

: LOCK55

: LOCK

[new==old]

new++

old = new

Inconsistent

new == oldReachability Tree

Page 39: Software Verification with BLAST

Repeat Build-and-Search

Predicates: LOCK, new==old

: LOCK

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

1

1

Reachability Tree

Page 40: Software Verification with BLAST

Repeat Build-and-Search

Predicates: LOCK, new==old

: LOCK

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

1

1

LOCK , new==old

2

2

lock()

old = new

q=q->next

Reachability Tree

Page 41: Software Verification with BLAST

Repeat Build-and-Search

Predicates: LOCK, new==old

: LOCK

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

1

1

LOCK , new==old

2

2

LOCK , new==old

3

3

4

4

q->data = new

unlock()

new++: LOCK , : new =

old

Reachability Tree

Page 42: Software Verification with BLAST

Repeat Build-and-Search

Predicates: LOCK, new==old

: LOCK

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

1

1

LOCK , new==old

2

2

LOCK , new==old

3

3

4

4

: LOCK , : new = old

[new==old]

Reachability Tree

Page 43: Software Verification with BLAST

Repeat Build-and-Search

Predicates: LOCK, new==old

: LOCK

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

1

1

LOCK , new==old

2

2

LOCK , new==old

3

3

4

4

: LOCK , : new = old

: LOCK, : new == old

1

[new!=old]

4

Reachability Tree

Page 44: Software Verification with BLAST

Repeat Build-and-Search

Predicates: LOCK, new==old

: LOCK

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

1

1

2

2

3

3

4

4

1

4

LOCK , new=old

4

4

: LOCK , new==old

55

SAFE

Reachability Tree

LOCK , new==old

LOCK , new==old

: LOCK , : new = old

: LOCK, : new == old

Page 45: Software Verification with BLAST

Key Idea: Reachability Tree

3

1

2

3

4 5

3

6

Error Free

7

1

8

8 1

SAFE

Unroll1. Pick tree-node (=abs. state)2. Add children (=abs. successors)3. On re-visiting abs. state, cut-off

Find min spurious suffix

- Learn new predicates- Rebuild subtree with new preds.

S1: Only Abstract Reachable States

S2: Don’t refine error-free regions

Initial

Page 46: Software Verification with BLAST

Lazy Abstraction

Abstract

Refine

C Program

Safe

Trace

Yes

NoPropert

y

Key Idea: Reachability Tree

Solution: 1. Abstract reachable states, 2. Avoid refining error-free regions

Problem: Abstraction is Expensive

Page 47: Software Verification with BLAST

Plan

• Motivation• Lazy Abstraction• Demo• Technical Details

Page 48: Software Verification with BLAST

Demo

Page 49: Software Verification with BLAST

Plan

• Motivation• Lazy Abstraction• Demo• Technical Details

Page 50: Software Verification with BLAST

Technical Details

Predicates: LOCK, new==old

: LOCK

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

1

1

2

2

3

3

4

4

1

4

LOCK , new=old

4

4

: LOCK , new==old

55

SAFE

Reachability Tree

LOCK , new==old

LOCK , new==old

: LOCK , : new = old

: LOCK, : new == old

Page 51: Software Verification with BLAST

Technical Details

Predicates: LOCK, new==old

: LOCK

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

1

1

2

2

3

3

4

4

1

4

LOCK , new=old

4

4

: LOCK , new==old

55

SAFE

Reachability Tree

LOCK , new==old

LOCK , new==old

: LOCK , : new = old

: LOCK, : new == old

3

4

LOCK , new==old

: LOCK , : new = old

q->data = new

unlock()

new++

Q. How to compute “successors” ?

Page 52: Software Verification with BLAST

Technical Details

: LOCK

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

1

1

2

2

3

3

4

4

1

4

LOCK , new=old

4

4

: LOCK , new==old

55

SAFE

LOCK , new==old

LOCK , new==old

: LOCK , : new = old

: LOCK, : new == old

Q. How to find predicates ?

Q. How to compute “successors” ?

Predicates: LOCK, new==old

Refinement

Page 53: Software Verification with BLAST

Plan

• Motivation• Lazy Abstraction• Demo• Technical Details

– Q: How to compute “successors” ?– Q: How to find predicates ?

Page 54: Software Verification with BLAST

Plan

• Motivation• Lazy Abstraction• Demo• Technical Details

– Q: How to compute “successors” ?– Q: How to find predicates ?– Q: How to analyze (recursive)

procedures ?

Page 55: Software Verification with BLAST

Plan

• Motivation• Lazy Abstraction• Demo• Technical Details

– Q: How to compute “successors” ?– Q: How to find predicates ?– Q: How to analyze (recursive)

procedures ?– Q: How to analyze long traces ?

Page 56: Software Verification with BLAST

Predicates: LOCK, new==old

Refinement

Technical Details

: LOCK

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

1

1

2

2

3

3

4

4

1

4

LOCK , new=old

4

4

: LOCK , new==old

55

SAFE

LOCK , new==old

LOCK , new==old

: LOCK , : new = old

: LOCK, : new == old

Q. How to compute “successors” ?

Page 57: Software Verification with BLAST

Weakest Preconditions

[P]

OP

[WP(P, OP)]WP(P,OP) Weakest formula P’ s.t. if P’ is true before OP then P is true after OP

Page 58: Software Verification with BLAST

Weakest Preconditions

[P]

OP

[WP(P, OP)]WP(P,OP) Weakest formula P’ s.t. if P’ is true before OP then P is true after OP

Assign x = e

P

P[e/x]

new = old

new = new+1

new+1 = old

Page 59: Software Verification with BLAST

Weakest Preconditions

P

c ) P

new = old

new=old ) new=old

[c]BranchAssume [new=old]

[P]

OP

[WP(P, OP)]WP(P,OP) Weakest formula P’ s.t. if P’ is true before OP then P is true after OP

Page 60: Software Verification with BLAST

How to compute successor ?

Predicates: LOCK, new==old

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

3

4

LOCK , new==old

: LOCK , : new = old

OP

For each p• Check if p is true (or false) after OP

Q: When is p true after OP ? - If WP(p, OP) is true before OP ! - We know F is true before OP

- Thm. Pvr. Query: F ) WP(p, OP)

F

?

Page 61: Software Verification with BLAST

How to compute successor ?

Predicates: LOCK, new==old

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

3

4

LOCK , new==old

OP

For each p• Check if p is true (or false) after OP

Q: When is p false after OP ? - If WP(: p, OP) is true before OP ! - We know F is true before OP

- Thm. Pvr. Query: F ) WP(: p, OP)

F

?

Page 62: Software Verification with BLAST

How to compute successor ?Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

3

4

LOCK , new==old

: new = old

OP

For each p• Check if p is true (or false) after OP

Q: When is p false after OP ? - If WP(: p, OP) is true before OP ! - We know F is true before OP

- Thm. Pvr. Query: F ) WP(: p, OP)

F

?

(LOCK , new==old) ) (new + 1 = old) (LOCK , new==old) ) (new + 1 old)

NO

YES

: LOCK , : new = old

Predicate: new==old

True ?

False ?

Page 63: Software Verification with BLAST

Plan

• Motivation• Lazy Abstraction• Demo• Technical Details

– Q: How to compute “successors” ?– Q: How to find predicates ?– Q: How to analyze (recursive)

procedures ?– Q: How to analyze long traces ?

Page 64: Software Verification with BLAST

Predicates: LOCK, new==old

Refinement

Technical Details

: LOCK

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

1

1

2

2

3

3

4

4

1

4

LOCK , new=old

4

4

: LOCK , new==old

55

SAFE

LOCK , new==old

LOCK , new==old

: LOCK , : new = old

: LOCK, : new == old

Q. How to find predicates ?

Page 65: Software Verification with BLAST

Tracking lock not enough

#Predicates grows with program size

Problem:p1,…,pn needed for verification

Exponential reachable abstract states

while(1){1: if (p1) lock() ; if (p1) unlock() ; …2: if (p2) lock() ; if (p2) unlock() ; … n: if (pn) lock() ; if (pn) unlock() ;}

while(1){1: if (p1) lock() ; if (p1) unlock() ; …2: if (p2) lock() ; if (p2) unlock() ; … n: if (pn) lock() ; if (pn) unlock() ;}

TF

T

Page 66: Software Verification with BLAST

#Predicates grows with program size

Problem:p1,…,pn needed for verification

Exponential reachable abstract states

while(1){1: if (p1) lock() ; if (p1) unlock() ; …2: if (p2) lock() ; if (p2) unlock() ; … n: if (pn) lock() ; if (pn) unlock() ;}

while(1){1: if (p1) lock() ; if (p1) unlock() ; …2: if (p2) lock() ; if (p2) unlock() ; … n: if (pn) lock() ; if (pn) unlock() ;}

: LOCK

: LOCK, p1

p1p2

p1: p2 : p1 p2 : p1: p2

LOCK, p1 : LOCK, : p1

: LOCK, : p1

2n Abstract States

: LOCK

Page 67: Software Verification with BLAST

Predicates useful locally

while(1){1: if (p1) lock() ; if (p1) unlock() ; …2: if (p2) lock() ; if (p2) unlock() ; … n: if (pn) lock() ; if (pn) unlock() ;}

while(1){1: if (p1) lock() ; if (p1) unlock() ; …2: if (p2) lock() ; if (p2) unlock() ; … n: if (pn) lock() ; if (pn) unlock() ;}

: LOCK

: LOCK , p1

LOCK , p1

: LOCK, : p1

: LOCK , : p1

2n Abstract States

p1

p2

pn

: LOCK : LOCK: LOCK

LOCK , p2

: LOCK , : p2

: LOCK

Solution: Use predicates only where needed

Using Counterexamples:Q1. Find predicatesQ2. Find where predicates are needed

Page 68: Software Verification with BLAST

Lazy Abstraction

Abstract

Refine

C Program

Safe

Trace

Yes

NoPropert

y

Refine Pred. MapPC Preds.

Ctrex.Trace

Solution: Localize pred. use, find where preds. needed

Problem: #Preds grows w/ Program Size

Page 69: Software Verification with BLAST

Counterexample Traces

1: x = ctr

2: ctr = ctr + 1

3: y = ctr

4: assume(x = i-1)

5: assume(y i)

y = x +1

1: x = ctr;2: ctr = ctr + 1;3: y = ctr;4: if (x = i-1){5: if (y != i){

ERROR: }

}

1: x = ctr;2: ctr = ctr + 1;3: y = ctr;4: if (x = i-1){5: if (y != i){

ERROR: }

}

Page 70: Software Verification with BLAST

Trace Formulas

1: x = ctr

2: ctr = ctr+1

3: y = ctr

4: assume(x=i-1)

5: assume(yi)

Trace SSA Trace

x1 = ctr0

Æ ctr1 = ctr0+ 1

Æ y1 = ctr1

Æ x1 = i0 - 1

Æ y1 i0

1: x1 = ctr0

2: ctr1 = ctr0+1

3: y1 = ctr1

4: assume(x1=i0-1)

5: assume(y1i0)

Trace FeasibilityFormula

Thm: Trace is feasible , TF is satisfiable

Page 71: Software Verification with BLAST

The Present State…

1: x = ctr

2: ctr = ctr + 1

3: y = ctr

4: assume(x = i-1)

5: assume(y i)

Trace

… is all the information the executing program has here

1. … after executing trace past (prefix)

2. … knows present values of variables

3. … makes trace future (suffix) infeasible

State…

At pc4, which predicate on present state shows infeasibility of future ?

Page 72: Software Verification with BLAST

What Predicate is needed ?

Trace

1: x = ctr

2: ctr = ctr + 1

3: y = ctr

4: assume(x = i-1)

5: assume(y i)

Trace Formula (TF)

x1 = ctr0

Æ ctr1 = ctr0 +1

Æ y1 = ctr1

Æ x1 = i0 - 1

Æ y1 i0

Page 73: Software Verification with BLAST

What Predicate is needed ?

Trace

1: x = ctr

2: ctr = ctr + 1

3: y = ctr

4: assume(x = i-1)

5: assume(y i)

Trace Formula (TF)

x1 = ctr0

Æ ctr1 = ctr0+ 1

Æ y1 = ctr1

Æ x1 = i0 - 1

Æ y1 i0

1. … after executing trace prefix

Relevant Information

… implied by TF prefix

Predicate …

Page 74: Software Verification with BLAST

1: x = ctr

2: ctr = ctr + 1

3: y = ctr

4: assume(x = i-1)

5: assume(y i)

1. … after executing trace prefix

2. … has present values of variables

What Predicate is needed ?

Trace Trace Formula (TF)

x1 = ctr0

Æ ctr1 = ctr0+ 1

Æ y1 = ctr1

Æ x1 = i0 - 1

Æ y1 i0

… implied by TF prefix

… on common variables

Predicate …

x1

x1

Relevant Information

Page 75: Software Verification with BLAST

1: x = ctr

2: ctr = ctr + 1

3: y = ctr

4: assume(x = i-1)

5: assume(y i)

1. … after executing trace prefix

2. … has present values of variables

3. … makes trace suffix infeasible

What Predicate is needed ?

Trace Trace Formula (TF)

x1 = ctr0

Æ ctr1 = ctr0+ 1

Æ y1 = ctr1

Æ x1 = i0 - 1

Æ y1 i0

… implied by TF prefix

… on common variables

… & TF suffix is unsatisfiable

Predicate …Relevant Information

Page 76: Software Verification with BLAST

1: x = ctr

2: ctr = ctr + 1

3: y = ctr

4: assume(x = i-1)

5: assume(y i)

What Predicate is needed ?

Trace Trace Formula (TF)

x1 = ctr0

Æ ctr1 = ctr0+ 1

Æ y1 = ctr1

Æ x1 = i0 - 1

Æ y1 i0

Predicate …

1. … after executing trace prefix

2. … has present values of variables

3. … makes trace suffix infeasible

… implied by TF prefix

… on common variables

… & TF suffix is unsatisfiable

Relevant Information

Page 77: Software Verification with BLAST

Interpolant = Predicate !

-

+

Interpolate

Trace Formula

x1 = ctr0

Æ ctr1 = ctr0+ 1

Æ y1 = ctr1

Æ x1 = i0 - 1

Æ y1 i0

y1 = x1 + 1

Predicate …

… implied by TF prefix

… on common variables

… & TF suffix is unsatisfiable

Craig Interpolant[Craig 57]

Computable from Proof of Unsat[Krajicek 97] [Pudlak 97]

1: x = ctr

2: ctr = ctr + 1

3: y = ctr

4: assume(x = i-1)

5: assume(y i)

Trace

Predicate at 4:y= x+1

Page 78: Software Verification with BLAST

Another interpretation …

-

+

Interpolate

Trace Formula

x1 = ctr0

Æ ctr1 = ctr0+ 1

Æ y1 = ctr1

Æ x1 = i0 - 1

Æ y1 i0

y1 = x1 + 1

Unsat = Empty Intersection = Trace Infeasible

Predicate at 4:y= x+1-

+

After execprefix

Canexecsuffix

Interpolant = Overapprox. states after prefix

that cannot execute suffix

Page 79: Software Verification with BLAST

Interpolant = Predicate !

-

+

Interpolate

Trace Formula

x1 = ctr0

Æ ctr1 = ctr0+ 1

Æ y1 = ctr1

Æ x1 = i0 - 1

Æ y1 i0

y1 = x1 + 1

Predicate …

… implied by TF prefix

… on common variables

… & TF suffix is unsatisfiable

Craig Interpolant[Craig 57]

Computable from Proof of Unsat[Krajicek 97] [Pudlak 97]

1: x = ctr

2: ctr = ctr + 1

3: y = ctr

4: assume(x = i-1)

5: assume(y i)

Trace

Predicate at 4:y= x+1

Page 80: Software Verification with BLAST

Interpolant = Predicate !

-

+

Interpolate

Trace Formula

x1 = ctr0

Æ ctr1 = ctr0+ 1

Æ y1 = ctr1

Æ x1 = i0 - 1

Æ y1 i0

y1 = x1 + 1

Predicate …

… implied by TF prefix

… on common variables

… & TF suffix is unsatisfiable

Craig Interpolant[Craig 57]

Computable from Proof of Unsat[Krajicek 97] [Pudlak 97]

1: x = ctr

2: ctr = ctr + 1

3: y = ctr

4: assume(x = i-1)

5: assume(y i)

Trace

Predicate at 4:y= x+1

Q. How to compute interpolants ? …

Page 81: Software Verification with BLAST

Building Predicate Maps

Trace Trace Formula

x1 = ctr0

Æ ctr1 = ctr0+ 1

Æ y1 = ctr1

Æ x1 = i0 - 1

Æ y1 i0

•Cut + Interpolate at each point

•Pred. Map: pci Interpolant from cut i

-

+x1 = ctr0

Predicate Map 2: x= ctr

1: x = ctr

2: ctr = ctr + 1

3: y = ctr

4: assume(x = i-1)

5: assume(y i)

Interpolate

Page 82: Software Verification with BLAST

Building Predicate Maps

Trace Trace Formula

x1 = ctr0

Æ ctr1 = ctr0+ 1

Æ y1 = ctr1

Æ x1 = i0 - 1

Æ y1 i0

-

+

1: x = ctr

2: ctr = ctr + 1

3: y = ctr

4: assume(x = i-1)

5: assume(y i)

Predicate Map 2: x = ctr3: x= ctr-1

x1= ctr1-1Interpolat

e

•Cut + Interpolate at each point

•Pred. Map: pci Interpolant from cut i

Page 83: Software Verification with BLAST

Building Predicate Maps

Trace Trace Formula

x1 = ctr0

Æ ctr1 = ctr0+ 1

Æ y1 = ctr1

Æ x1 = i0 - 1

Æ y1 i0

1: x = ctr

2: ctr = ctr + 1

3: y = ctr

4: assume(x = i-1)

5: assume(y i)

Predicate Map 2: x = ctr3: x= ctr - 14: y= x + 1

y1= x1+1

-

+

Interpolate

•Cut + Interpolate at each point

•Pred. Map: pci Interpolant from cut i

Page 84: Software Verification with BLAST

Building Predicate Maps

Trace Trace Formula

x1 = ctr0

Æ ctr1 = ctr0+ 1

Æ y1 = ctr1

Æ x1 = i0 - 1

Æ y1 i0

1: x = ctr

2: ctr = ctr + 1

3: y = ctr

4: assume(x = i-1)

5: assume(y i)

Predicate Map 2: x = ctr3: x= ctr - 14: y= x + 15: y = i

y1= i0

-

+

Interpolate

•Cut + Interpolate at each point

•Pred. Map: pci Interpolant from cut i

Page 85: Software Verification with BLAST

Local Predicate Use

Predicate Map 2: x = ctr3: x= ctr - 14: y= x + 15: y = i

Use predicates needed at location

• #Preds. grows with program size

• #Preds per location small

Local Predicate use

Ex: 2n states

Global Predicate use

Ex: 2n states

Verification scales …

Page 86: Software Verification with BLAST

Localizing

Program

Lines* PreviousTime(min

s)

Time(mins)

Predicates Total

Average

kbfiltr 12k 1 3 72 6.5

floppy 17k 7 25 240 7.7

diskprf 14k 5 13 140 10

cdaudio 18k 20 23 256 7.8

parport 61k DNF 74 753 8.1

parclss 138k DNF 77 382 7.2

* Pre-processed

Property3:

IRP Handler

Win NT DDK

Page 87: Software Verification with BLAST

Lazy Abstraction

Abstract

Refine

C Program

Safe

Trace

Yes

NoPropert

y

Refine TraceFeas

FormulaThm Pvr

Proof of Unsat

Pred. MapPC Preds.

Ctrex.Trace

Interpolate

Solution: Localize pred. use, find where preds. needed

Problem: #Preds grows w/ Program Size

Page 88: Software Verification with BLAST

So far …Lazy Abstraction

• Predicates:– Abstract infinite program states

• Counterexample-guided Refinement:– Find predicates tailored to prog, property

1. Abstraction : Expensive Reachability Tree

2. Refinement : Find predicates, use locations Proof of unsat of TF + Interpolation

Page 89: Software Verification with BLAST

Plan

• Motivation• Lazy Abstraction• Demo• Technical Details

– Q: How to compute “successors” ?– Q: How to find predicates ?– Q: How to analyze (recursive)

procedures ?– Q: How to analyze long traces ?

Page 90: Software Verification with BLAST

Predicates: LOCK, new==old

Refinement

Technical Details

: LOCK

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

1

1

2

2

3

3

4

4

1

4

LOCK , new=old

4

4

: LOCK , new==old

55

SAFE

LOCK , new==old

LOCK , new==old

: LOCK , : new = old

: LOCK, : new == old

Q. How to analyze recursive procedures ?

Page 91: Software Verification with BLAST

An example

main(){ 1: if (flag){2: y = inc(x,flag);3: if (y<=x) ERROR; } else {4: y = inc(z,flag);5: if (y>=z) ERROR; }return;}

main(){ 1: if (flag){2: y = inc(x,flag);3: if (y<=x) ERROR; } else {4: y = inc(z,flag);5: if (y>=z) ERROR; }return;}

inc(int a, int sign){ 1: if (sign){2: rv = a+1; } else {3: rv = a-1; }4: return rv;}

inc(int a, int sign){ 1: if (sign){2: rv = a+1; } else {3: rv = a-1; }4: return rv;}

Page 92: Software Verification with BLAST

Inline Calls in Reach Treemain(){ 1: if (flag){2: y = inc(x,flag);3: if (y<=x) ERROR; } else {4: y = inc(z,flag);5: if (y>=z) ERROR; }return;}

main(){ 1: if (flag){2: y = inc(x,flag);3: if (y<=x) ERROR; } else {4: y = inc(z,flag);5: if (y>=z) ERROR; }return;}

inc(int a, int sign){ 1: if (sign){2: rv = a+1; } else {3: rv = a-1; }4: return rv;}

inc(int a, int sign){ 1: if (sign){2: rv = a+1; } else {3: rv = a-1; }4: return rv;}

1

2

1,2

Initial

2,2

4,2

3,2

4,2

3 3

4

1,4

2,4

4,4

3,4

4,4

5 5

Page 93: Software Verification with BLAST

Inline Calls in Reach Tree

1

2

1,2

Initial

2,2

4,2

3,2

4,2

3 3

4

1,4

2,4

4,4

3,4

4,4

5 5

Problem- Repeated analysis for “inc”- Exploding call contexts

int x; //globalf1(){1: x = 0;2: if(*) f2();3: else f2(); 4: if (x<0) ERROR;return;}

int x; //globalf1(){1: x = 0;2: if(*) f2();3: else f2(); 4: if (x<0) ERROR;return;}

f2(){1: if(*) f3();2: else f3(); return;}

f2(){1: if(*) f3();2: else f3(); return;}

f3(){1: if(*) f4();2: else f4(); return;}

f3(){1: if(*) f4();2: else f4(); return;}

f4(){1: if(*) f5();2: else f5(); return;}

f4(){1: if(*) f5();2: else f5(); return;}

fn(){1: x ++; return;}

fn(){1: x ++; return;}

2n nodes in Reach Tree

Page 94: Software Verification with BLAST

Inline Calls in Reach Tree

1

2

1,2

Initial

2,2

4,2

3,2

4,2

3 3

4

1,4

2,4

4,4

3,4

4,4

5 5

Problem- Repeated analysis for “inc”- Exploding call contexts- Cyclic call graph (Recursion)

- Infinite Tree!

Page 95: Software Verification with BLAST

Solution : Procedure SummariesSummaries: Input/Output behavior• Plug summaries in at each callsite … instead of inlining entire procedure[Sharir-Pnueli 81, Reps-Horwitz-Sagiv 95]

• Summary = set of (F F’)– F : Precondition formula describing input

state– F’ : Postcondition formula describing output

state

Page 96: Software Verification with BLAST

Solution : Procedure SummariesSummaries: Input/Output behavior• Plug summaries in at each callsite … instead of inlining entire procedure[Sharir-Pnueli 81, Reps-Horwitz-Sagiv 95, Ball-Rajamani 01]

• Summary = set of (F F’)– F : Precondition formula describing input

state– F’ : Postcondition formula describing output

state

inc(int a, int sign){ 1: if (sign){2: rv = a+1; } else {3: rv = a-1; }4: return rv;}

inc(int a, int sign){ 1: if (sign){2: rv = a+1; } else {3: rv = a-1; }4: return rv;}

• (: sign=0 rv > a) • (sign = 0 rv < a)

Q. How to compute, use summaries ?

Page 97: Software Verification with BLAST

Lazy Abstraction + Procedure Summaries

Abstract

Refine

C Program

Safe

Trace

Yes

NoPropert

y

Q. How to compute, use summaries ?

Page 98: Software Verification with BLAST

Abstraction with Summariesmain(){ 1: if (flag){2: y = inc(x,flag);3: if (y<=x) ERROR; } else {4: y = inc(z,flag);5: if (y>=z) ERROR; }return;}

main(){ 1: if (flag){2: y = inc(x,flag);3: if (y<=x) ERROR; } else {4: y = inc(z,flag);5: if (y>=z) ERROR; }return;}

inc(int a, int sign){ 1: if (sign){2: rv = a+1; } else {3: rv = a-1; }4: return rv;}

inc(int a, int sign){ 1: if (sign){2: rv = a+1; } else {3: rv = a-1; }4: return rv;}

1

2

main

Predicates: flag=0 , y>x , y<z

sign=0 , rv>a , rv<a

: flag=0 a=x

sign=flag:

sign=0

[flag!=0]

Page 99: Software Verification with BLAST

Abstraction with Summariesmain(){ 1: if (flag){2: y = inc(x,flag);3: if (y<=x) ERROR; } else {4: y = inc(z,flag);5: if (y>=z) ERROR; }return;}

main(){ 1: if (flag){2: y = inc(x,flag);3: if (y<=x) ERROR; } else {4: y = inc(z,flag);5: if (y>=z) ERROR; }return;}

inc(int a, int sign){ 1: if (sign){2: rv = a+1; } else {3: rv = a-1; }4: return rv;}

inc(int a, int sign){ 1: if (sign){2: rv = a+1; } else {3: rv = a-1; }4: return rv;}

1

2

1

main

2

4

Predicates: flag=0 , y>x , y<z

sign=0 , rv>a , rv<a

inc

: flag=0

: sign=0

a=x

sign=flag:

sign=0

[sign!=0]

: sign=0rv=a+1

rv>a

Summary: (: sign=0 rv>a),

Page 100: Software Verification with BLAST

Summary Successormain(){ 1: if (flag){2: y = inc(x,flag);3: if (y<=x) ERROR; } else {4: y = inc(z,flag);5: if (y>=z) ERROR; }return;}

main(){ 1: if (flag){2: y = inc(x,flag);3: if (y<=x) ERROR; } else {4: y = inc(z,flag);5: if (y>=z) ERROR; }return;}

inc(int a, int sign){ 1: if (sign){2: rv = a+1; } else {3: rv = a-1; }4: return rv;}

inc(int a, int sign){ 1: if (sign){2: rv = a+1; } else {3: rv = a-1; }4: return rv;}

1

2

1

main

2

4

Predicates: flag=0 , y>x , y<z

sign=0 , rv>a , rv<a

inc

: flag=0

: sign=0

rv>a

Summary: (: sign=0 rv>a),

3

a=x

sign=flag

y>xassume rv>ay=rv

Page 101: Software Verification with BLAST

Abstraction with Summariesmain(){ 1: if (flag){2: y = inc(x,flag);3: if (y<=x) ERROR; } else {4: y = inc(z,flag);5: if (y>=z) ERROR; }return;}

main(){ 1: if (flag){2: y = inc(x,flag);3: if (y<=x) ERROR; } else {4: y = inc(z,flag);5: if (y>=z) ERROR; }return;}

inc(int a, int sign){ 1: if (sign){2: rv = a+1; } else {3: rv = a-1; }4: return rv;}

inc(int a, int sign){ 1: if (sign){2: rv = a+1; } else {3: rv = a-1; }4: return rv;}

1

2

1

main

2

4

Predicates: flag=0 , y>x , y<z

sign=0 , rv>a , rv<a

inc

: flag=0

: sign=0

rv>a

Summary: (: sign=0 rv>a),

3y>x

[y<=x]

34 flag=0

a=z

sign=flag

sign=0

[sign=0][flag==0]

Page 102: Software Verification with BLAST

Abstraction with Summariesmain(){ 1: if (flag){2: y = inc(x,flag);3: if (y<=x) ERROR; } else {4: y = inc(z,flag);5: if (y>=z) ERROR; }return;}

main(){ 1: if (flag){2: y = inc(x,flag);3: if (y<=x) ERROR; } else {4: y = inc(z,flag);5: if (y>=z) ERROR; }return;}

inc(int a, int sign){ 1: if (sign){2: rv = a+1; } else {3: rv = a-1; }4: return rv;}

inc(int a, int sign){ 1: if (sign){2: rv = a+1; } else {3: rv = a-1; }4: return rv;}

1

2

1

main

2

4

Predicates: flag=0 , y>x , y<z

sign=0 , rv>a , rv<a

inc

: flag=0

: sign=0

rv>a

Summary: (: sign=0 rv>a),

(sign=0 rv<a)

3y>x

34 flag=0

a=z

sign=flag

sign=0

1 sign=0

2 3

4 rv<a

Page 103: Software Verification with BLAST

Summary Successormain(){ 1: if (flag){2: y = inc(x,flag);3: if (y<=x) ERROR; } else {4: y = inc(z,flag);5: if (y>=z) ERROR; }return;}

main(){ 1: if (flag){2: y = inc(x,flag);3: if (y<=x) ERROR; } else {4: y = inc(z,flag);5: if (y>=z) ERROR; }return;}

inc(int a, int sign){ 1: if (sign){2: rv = a+1; } else {3: rv = a-1; }4: return rv;}

inc(int a, int sign){ 1: if (sign){2: rv = a+1; } else {3: rv = a-1; }4: return rv;}

1

2

1

main

2

4

Predicates: flag=0 , y>x , y<z

sign=0 , rv>a , rv<a

inc

: flag=0

: sign=0

rv>a

Summary: (: sign=0 rv>a),

(sign=0 rv<a)

3y>x

34 flag=0

1 sign=0

2 3

4 rv<a

a=x

sign=flag

assume rv<ay=rv

3 y<z

Page 104: Software Verification with BLAST

Abstraction with Summariesmain(){ 1: if (flag){2: y = inc(x,flag);3: if (y<=x) ERROR; } else {4: y = inc(z,flag);5: if (y>=z) ERROR; }return;}

main(){ 1: if (flag){2: y = inc(x,flag);3: if (y<=x) ERROR; } else {4: y = inc(z,flag);5: if (y>=z) ERROR; }return;}

inc(int a, int sign){ 1: if (sign){2: rv = a+1; } else {3: rv = a-1; }4: return rv;}

inc(int a, int sign){ 1: if (sign){2: rv = a+1; } else {3: rv = a-1; }4: return rv;}

1

2

1

main

2

4

Predicates: flag=0 , y>x , y<z

sign=0 , rv>a , rv<a

inc

: flag=0

: sign=0

rv>a

Summary: (: sign=0 rv>a),

(sign=0 rv<a)

3y>x

34 flag=0

1 sign=0

2 3

4 rv<a

3 y<z

[y>=z]

Page 105: Software Verification with BLAST

Another Call …main(){ 1: if (flag){2: y = inc(x,flag);3: if (y<=x) ERROR; } else {4: y = inc(z,flag);5: if (y>=z) ERROR; }6: y1 = inc(z1,1);7: if (y1<=z1) ERROR;return;}

main(){ 1: if (flag){2: y = inc(x,flag);3: if (y<=x) ERROR; } else {4: y = inc(z,flag);5: if (y>=z) ERROR; }6: y1 = inc(z1,1);7: if (y1<=z1) ERROR;return;}

inc(int a, int sign){ 1: if (sign){2: rv = a+1; } else {3: rv = a-1; }4: return rv;}

inc(int a, int sign){ 1: if (sign){2: rv = a+1; } else {3: rv = a-1; }4: return rv;}

1

2

1

main

2

4

inc

: flag=0

: sign=0

rv>a

Summary: (: sign=0 rv>a),

(sign=0 rv<a)

3

6

y>x

34 flag=0

1 sign=0

2 3

4 rv<a

3 y<z

a=z1

sign=1: sign=0

6

Predicates: flag=0 ,y>x,y<z, y1>z1

sign=0 , rv>a , rv<a

Page 106: Software Verification with BLAST

Another Call …main(){ 1: if (flag){2: y = inc(x,flag);3: if (y<=x) ERROR; } else {4: y = inc(z,flag);5: if (y>=z) ERROR; }6: y1 = inc(z1,1);7: if (y1<=z1) ERROR;return;}

main(){ 1: if (flag){2: y = inc(x,flag);3: if (y<=x) ERROR; } else {4: y = inc(z,flag);5: if (y>=z) ERROR; }6: y1 = inc(z1,1);7: if (y1<=z1) ERROR;return;}

inc(int a, int sign){ 1: if (sign){2: rv = a+1; } else {3: rv = a-1; }4: return rv;}

inc(int a, int sign){ 1: if (sign){2: rv = a+1; } else {3: rv = a-1; }4: return rv;}

1

2

1

main

2

4

Predicates: flag=0 ,y>x,y<z, y1>z1

sign=0 , rv>a , rv<a

inc

: flag=0

: sign=0

rv>a

Summary: (: sign=0 rv>a),

(sign=0 rv<a)

3

6

y>x

34 flag=0

1 sign=0

2 3

4 rv<a

3 y<z

7

a=z1

sign=1

assume rv>ay1=rv

6

y1>z1SAFE

Page 107: Software Verification with BLAST

Plan

• Motivation• Lazy Abstraction• Demo• Technical Details

– Q: How to compute “successors” ?– Q: How to find predicates ?– Q: How to analyze (recursive)

procedures ?– Q: How to analyze long traces ?

Page 108: Software Verification with BLAST

Predicates: LOCK, new==old

Refinement

Technical Details

: LOCK

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

Example ( ) {1: do{ lock(); old = new; q = q->next;2: if (q != NULL){3: q->data = new; unlock(); new ++; }4:}while(new != old);5: unlock ();}

1

1

2

2

3

3

4

4

1

4

LOCK , new=old

4

4

: LOCK , new==old

55

SAFE

LOCK , new==old

LOCK , new==old

: LOCK , : new = old

: LOCK, : new == old

Q. How to analyze long traces ?

Page 109: Software Verification with BLAST

Example

Example ( ) {1:c = 0;2:for(i=1;i<1000;i+

+)3: c = c + f(i);

4:if (a>0) {5: if (x==0) {ERR: ; } }}

Example ( ) {1:c = 0;2:for(i=1;i<1000;i+

+)3: c = c + f(i);

4:if (a>0) {5: if (x==0) {ERR: ; } }}

• Assume f always terminates

• ERR is reachable– a and x are unconstrained

• Any feasible path to error must unroll the loop 1000 times AND find feasible paths through f

• Any other path must be dismissed as a false positive

Page 110: Software Verification with BLAST

Example

Example ( ) {1:c = 0;2:for(i=1;i<1000;i++)3: c = c + f(i);

4:if (a>0) {5: if (x==0) {ERR: ; } }}

Example ( ) {1:c = 0;2:for(i=1;i<1000;i++)3: c = c + f(i);

4:if (a>0) {5: if (x==0) {ERR: ; } }}

• Intuitively, the for loop is irrelevant

• ERR reachable as long as there exists some path from 2 to 4 that does not modify a or x

• Can we use static analysis to precisely report a statement is reachable without finding a feasible path?

Page 111: Software Verification with BLAST

Example

Example ( ) {1:c = 0;2:for(i=1;i<1000;i++)3: c = c + f(i);

4:if (a>0) {5: if (x==0) {ERR: ; } }}

Example ( ) {1:c = 0;2:for(i=1;i<1000;i++)3: c = c + f(i);

4:if (a>0) {5: if (x==0) {ERR: ; } }}

c = 01

i = 12

i¸1000

2’

3c = c + f(i);i++

4

2’

i<1000

a>0

x==05

1

4

a>0

x==05

Page 112: Software Verification with BLAST

Path Slice, Formally

The path slice of a program path is a subsequence of the edges of such that if the sequence of operations along the subsequence is:

1. infeasible, then is infeasible, and2. feasible, then the last location of

is reachable (but not necessarily along )

Page 113: Software Verification with BLAST

Computing Path Slices

• Intuitively, drop some edges, but leave branches that must be taken to reach the target, and assignments that feed into the branch conditions

• Backward dataflow over the path, tracking at each node– step location: source location of the last edge along the

path added to the slice

– live variables: set of relevant variables whose values determine whether or not the target is reachable along the suffix

Page 114: Software Verification with BLAST

Example

c = 01

i = 12

i¸1000

2’

3c = c + f(i);i++

4

2’

i<1000

a>0

x==05

ERR, {}

Example ( ) {1:c = 0;2:for(i=1;i<1000;i+

+)3: c = c + f(i);

4:if (a>0) {5: if (x==0) {ERR: ; } }}

Example ( ) {1:c = 0;2:for(i=1;i<1000;i+

+)3: c = c + f(i);

4:if (a>0) {5: if (x==0) {ERR: ; } }}

A conditional is taken if either(1) there is a path from the currentnode to the step location on whicha live variable is modified, or

(2) the current node does notpost-dominate the step location

Page 115: Software Verification with BLAST

Conditionals

current

step

X = …

x2 Live current

step

Page 116: Software Verification with BLAST

Example

c = 01

i = 12

i¸1000

2’

3c = c + f(i);i++

4

2’

i<1000

a>0

x==05

ERR, {}

Example ( ) {1:c = 0;2:for(i=1;i<1000;i+

+)3: c = c + f(i);

4:if (a>0) {5: if (x==0) {ERR: ; } }}

Example ( ) {1:c = 0;2:for(i=1;i<1000;i+

+)3: c = c + f(i);

4:if (a>0) {5: if (x==0) {ERR: ; } }}

Live = (Live n Wr(op)) [ Rd(op)

A conditional is taken if either(1) there is a path from the currentnode to the step location on whicha live variable is modified, or

(2) the current node does notpost-dominate the step location

Page 117: Software Verification with BLAST

Example

c = 01

i = 12

i¸1000

2’

3c = c + f(i);i++

4

2’

i<1000

a>0

x==05

ERR, {}

Example ( ) {1:c = 0;2:for(i=1;i<1000;i+

+)3: c = c + f(i);

4:if (a>0) {5: if (x==0) {ERR: ; } }}

Example ( ) {1:c = 0;2:for(i=1;i<1000;i+

+)3: c = c + f(i);

4:if (a>0) {5: if (x==0) {ERR: ; } }}

Page 118: Software Verification with BLAST

Example

c = 01

i = 12

i¸1000

2’

3c = c + f(i);i++

4

2’

i<1000

a>0

x==05

ERR, {}

5, {x}

Example ( ) {1:c = 0;2:for(i=1;i<1000;i+

+)3: c = c + f(i);

4:if (a>0) {5: if (x==0) {ERR: ; } }}

Example ( ) {1:c = 0;2:for(i=1;i<1000;i+

+)3: c = c + f(i);

4:if (a>0) {5: if (x==0) {ERR: ; } }}

4, {x, a}

4, {x, a}

Page 119: Software Verification with BLAST

Example

c = 01

i = 12

i¸1000

2’

3c = c + f(i);i++

4

2’

i<1000

a>0

x==05

ERR, {}

5, {x}

Example ( ) {1:c = 0;2:for(i=1;i<1000;i+

+)3: c = c + f(i);

4:if (a>0) {5: if (x==0) {ERR: ; } }}

Example ( ) {1:c = 0;2:for(i=1;i<1000;i+

+)3: c = c + f(i);

4:if (a>0) {5: if (x==0) {ERR: ; } }}

4, {x, a}

4, {x, a}

An assignment is taken if theassigned variable is in the Live set

Page 120: Software Verification with BLAST

Example

c = 01

i = 12

i¸1000

2’

3c = c + f(i);i++

4

2’

i<1000

a>0

x==05

ERR, {}

5, {x}

Example ( ) {1:c = 0;2:for(i=1;i<1000;i+

+)3: c = c + f(i);

4:if (a>0) {5: if (x==0) {ERR: ; } }}

Example ( ) {1:c = 0;2:for(i=1;i<1000;i+

+)3: c = c + f(i);

4:if (a>0) {5: if (x==0) {ERR: ; } }}

4, {x, a}

4, {x, a}

4, {x, a}

4, {x, a}

4, {x, a}

4, {x, a}

Page 121: Software Verification with BLAST

Slice1

4

a>0

x==05

Example ( ) {1:c = 0;2:for(i=1;i<1000;i+

+)3: c = c + f(i);

4:if (a>0) {5: if (x==0) {ERR: ; } }}

Example ( ) {1:c = 0;2:for(i=1;i<1000;i+

+)3: c = c + f(i);

4:if (a>0) {5: if (x==0) {ERR: ; } }}

Page 122: Software Verification with BLAST

Example 2: Infeasible PathExample ( ) {A:if (a>0) {B: x = 1;}1: c = 0;2:for(i=1;i<1000;i++)3: c = c + f(i);

4:if (a>0) {5: if (x==0) {ERR: ; } }}

Example ( ) {A:if (a>0) {B: x = 1;}1: c = 0;2:for(i=1;i<1000;i++)3: c = c + f(i);

4:if (a>0) {5: if (x==0) {ERR: ; } }}

c = 01

i = 12

i¸1000

2’

3c=c+f(i);i++

4

2’

i<1000

a>0

x==05

ERR, {}

5, {x}

4, {x, a}

4, {x, a}

4, {x, a}

4, {x, a}

4, {x, a}

4, {x, a}

Page 123: Software Verification with BLAST

Example 2: Infeasible PathExample ( ) {A:if (a>0) {B: x = 1;}1: c = 0;2:for(i=1;i<1000;i++)3: c = c + f(i);

4:if (a>0) {5: if (x==0) {ERR: ; } }}

Example ( ) {A:if (a>0) {B: x = 1;}1: c = 0;2:for(i=1;i<1000;i++)3: c = c + f(i);

4:if (a>0) {5: if (x==0) {ERR: ; } }}

c = 01

i = 12

i¸1000

2’

3c = c + f(i);i++

4

2’

i<1000

4, {x, a}

4, {x, a}

4, {x, a}

4, {x, a}

4, {x, a}

4, {x, a}

A

B B, {a}

x = 1

a>0

Live = (Live n Wr(op)) [ Rd(op)

A, {a}

Page 124: Software Verification with BLAST

Slice

1

4

a>0

x==05

A

B

x = 1

a>0

Infeasible Sliceimplies

Infeasible trace

Example ( ) {A:if (a>0) {B: x = 1;}1: c = 0;2:for(i=1;i<1000;i++)3: c = c + f(i);

4:if (a>0) {5: if (x==0) {ERR: ; } }}

Example ( ) {A:if (a>0) {B: x = 1;}1: c = 0;2:for(i=1;i<1000;i++)3: c = c + f(i);

4:if (a>0) {5: if (x==0) {ERR: ; } }}

Page 125: Software Verification with BLAST

Lazy Abstraction: Summary

Abstract

Refine

C Program

Safe

Trace

Yes

NoProperty

PathSlice

Page 126: Software Verification with BLAST

Lazy Abstraction: Summary• Predicates:

– Abstract infinite program states

• Counterexample-guided Refinement:– Find predicates tailored to prog, property

1. Abstraction : Expensive Reachability Tree, Procedure summaries

2. Refinement : Find predicates, use locations Slice irrelevant detailsProof of unsat of TF + Interpolation

Page 127: Software Verification with BLAST

Verification by Theorem Proving

1. Loop Invariants2. Logical formula3. Check Validity

Invariant: lock Æ new = old

Ç : lock Æ new old

Example ( ) {1: do{ lock(); old = new;

q = q->next;2: if (q != NULL){3: q->data = new;

unlock(); new ++; }4: } while(new != old);5: unlock (); return;}

Example ( ) {1: do{ lock(); old = new;

q = q->next;2: if (q != NULL){3: q->data = new;

unlock(); new ++; }4: } while(new != old);5: unlock (); return;}

Page 128: Software Verification with BLAST

Verification by Theorem Proving

1. Loop Invariants2. Logical formula3. Check Validity

- Loop Invariants- Multithreaded Programs + Behaviors encoded in logic+ Decision Procedures-

Example ( ) {1: do{ lock(); old = new;

q = q->next;2: if (q != NULL){3: q->data = new;

unlock(); new ++; }4: } while(new != old);5: unlock (); return;}

Example ( ) {1: do{ lock(); old = new;

q = q->next;2: if (q != NULL){3: q->data = new;

unlock(); new ++; }4: } while(new != old);5: unlock (); return;} Precis

e[ESC]

Page 129: Software Verification with BLAST

Verification by Program Analysis

1. Dataflow Facts2. Constraint

System3. Solve constraints

Example ( ) {1: do{ lock(); old = new;

q = q->next;2: if (q != NULL){3: q->data = new;

unlock(); new ++; }4: } while(new != old);5: unlock (); return;}

Example ( ) {1: do{ lock(); old = new;

q = q->next;2: if (q != NULL){3: q->data = new;

unlock(); new ++; }4: } while(new != old);5: unlock (); return;}

- Imprecision due to fixed facts

+ Abstraction

+ Type/Flow AnalysesScalable[CQUAL, ESP, MC]

Page 130: Software Verification with BLAST

Verification by Model Checking

1. (Finite State) Program

2. State Transition Graph

3. Reachability

Example ( ) {1: do{ lock(); old = new;

q = q->next;2: if (q != NULL){3: q->data = new;

unlock(); new ++; }4: } while(new != old);5: unlock (); return;}

Example ( ) {1: do{ lock(); old = new;

q = q->next;2: if (q != NULL){3: q->data = new;

unlock(); new ++; }4: } while(new != old);5: unlock (); return;}

- Pgm ! Finite state model

- State explosion + State Exploration+ CounterexamplesPrecise[SPIN, SMV, Bandera,JPF ]

Page 131: Software Verification with BLAST

Combining StrengthsTheorem Proving

- loop invariants

+ Behaviors encoded in logicRefine+ Theorem proversComputing Successors,Refine

Program Analysis

- Imprecise+ AbstractionShrink state space

Model Checking- Finite-state model, state explosion+ State Space ExplorationPath Sensitive Analysis+ CounterexamplesFinding Relevant Facts

Lazy Abstraction

Page 132: Software Verification with BLAST

Thank you

http://www.eecs.berkeley.edu/~blast