<<

Model Checking, Proving, and Abstract Interpretation: The Convergence of Formal Verification Technologies

Tom Henzinger EPFL Three Verification Communities

: -automatic, but inefficient (does not scale) -successful in hardware verification

• Theorem proving: -precise, but interactive (requires user intervention) -much recent progress in decision procedures

• Static analysis: -efficient, but imprecise (many false positives) -standard in compilers Convergence

• Not just interaction of model checkers, theorem provers, and static analyzers via a shared code database

• But deep integration of the three technologies within a single tool

• Is it a model checker exploring states? A theorem prover manipulating formulas? A static analyzer interpreting an abstract program? All of the above ! Property Checking

• Programmer gives partial specifications – Is there a complete spec for Word ? Emacs ? – Often implicit: code annotations, memory safety, race freedom

• Code checked for with specification

• Different from program correctness – Partial specs of large programs rather than complete specs of small programs Interface Usage Rules

• Rules in documentation – Order of operations and data access – Incomplete, unenforced, wordy

• Rule violations lead to bad behavior – System crash or deadlock – Unexpected exceptions Property 1: Double Locking

lock

unlock

unlock lock

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

Calls to lock and unlock must alternate. Property 2: IRP Handler

start NP CallDriver SKIP1 SKIP2 return Skip child status CallDriver IPC MPR3 synch d NP rne prop CallDriver etu ng r completion PPC ndi MPR t pe Complete no completion CallDriver MPR1 request return MPR2 DC not Pend no prop synch completion CallDriver IRP accessible N/A N/A

start P CallDriver Mark Pending SKIP1 SKIP2 Skip CallDriver IPC MPR3 synch ed NP CallDriver return turn prop g re PPC Pending din completion en MPR Complete not p CallDriver completion request MPR2 MPR1 DC no prop completion CallDriver Win NT DDK N/A [Fahndrich] Locking Example

ExampleExample ()() {{ 11::do do {{ lock();lock(); oldold == new;new; lock qq == q->next;q->next; 2: if (q != NULL) { 2: if (q != NULL) { unlock 33::q->data q->data == new;new; unlock();unlock(); unlock lock newnew ++;++; }} 44::} } whilewhile (new(new !=!= old);old); 55:: unlock();unlock(); return;return; }} The Model Checking View: Programs are State Transition Systems

state transition

pc → 3 33:: unlock();unlock(); pc → 4 lock → new++;new++; lock → old → 5 44:: old → 5 new → 5 new → 6 q → 0x133a q → 0x133a

ExampleExample ()() {{ 11:: dodo {{ lock();lock(); oldold == newnew;; qq == q->next;q->next; 22:: ifif (q(q !=!= NULL)NULL) {{ 33:: q->dataq->data == new;new; unlock();unlock(); newnew ++;++; [Clarke-Emerson, Queille-Sifakis] }} 44:: }} whilewhile (new(new !=!= old);old); 55:: unlock();unlock(); return;}return;} The Safety Verification Problem

Error

Safe

Theorem proving: guess and verify inductive invariant Initial

Is there a path from an initial state to an error state ? The Safety Verification Problem

Error

Safe

Model checking: explore all reachable states Initial

Is there a path from an initial state to an error state ? Problem: infinite state graph Solution: of states ' logical formula Abstraction

•Predicateson program state: lock old = new

• States satisfying same predicates are equivalent: merged into one abstract state

• Number of abstract states is finite

[Cousot-Cousot, Graf-Saidi] Abstract States and Transitions

pc → 3 33:: unlock();unlock(); pc → 4 lock → new++;new++; lock → old → 5 44:: old → 5 new → 5 new → 6 q → 0x133a q → 0x133a

Theorem Prover lock ¬ lock [Cousot-Cousot, Graf-Saidi] old=new ¬ old=new Abstraction

pc → 3 33:: unlock();unlock(); pc → 4 lock → new++;new++; lock → old → 5 44:: old → 5 new → 5 new → 6 q → 0x133a q → 0x133a

Theorem Prover lock ¬ lock Existential Lifting old=new ¬ old=new Analyze Abstraction

• Analyze finite graph

• Overapproximation: –safe ⇒ program safe – no false negatives

•Problem: spurious counterexamples – false positives! Counterexample-guided Refinement

Solution: Use spurious counterexamples to refine abstraction

1. Add predicates to distinguish states across cut Imprecision due to merge Iterative Abstraction Refinement

Solution: Use spurious counterexamples to refine abstraction

1. Add predicates to distinguish states across cut 2. Build refined abstraction eliminates counterexample 3. Repeat search until real counterexample found [Kurshan et al., Clarke et al.] or program proved safe [Ball-Rajamani 01: SLAM] How to Compute Successors ?

ExampleExample (( )) {{ 11:: do{do{ LOCK , new=old 3 F lock();lock(); oldold == new;new; OP q = q->next; q = q->next; 4 22:: ifif (q(q !=!= NULL){NULL){ ¬ LOCK , ¬ new=old ? 33:: q->dataq->data == new;new; unlock(); unlock(); For each predicate p newnew ++;++; }} check if p is true (or false) after OP 44:}while(new:}while(new !=!= old);old); 55:: unlock();unlock(); }} Q: When is p true after OP ? -if WP( p,OP) is true before OP - we know F is true before OP - Thm Prover query: F ⇒ WP( p, OP) ?

Predicates: LOCK, new=old How to Compute Successors ?

ExampleExample (( )) {{ 1: do{ 1: do{ LOCK , new=old 3 q->data = new lock(); F lock(); unlock() oldold == new;new; q = q->next; new++ q = q->next; 4 22:: ifif (q(q !=!= NULL){NULL){ ¬ LOCK , ¬ new=old ? 33:: q->dataq->data == new;new; unlock(); unlock(); For each predicate p newnew ++;++; }} check if p is true (or false) after OP 44:}while(new:}while(new !=!= old);old); 55:: unlock();unlock(); }} Q: When is p true after OP ? -if WP( p, OP) is true before OP - we know F is true before OP - Thm Prover query: F ⇒ WP( p, OP) Predicate: new=old

True ? (LOCK , new=old) ⇒ (new + 1 = old) NO False ? (LOCK , new=old) ⇒ (new + 1 ≠ old) YES Abstraction is Expensive

Reachable

Problem: Observe: #predicates -#abstract states = 2 often only fraction of state space -exponential Thm Prover queries reachable Abstract Only Reachable States

Safe

Problem: Solution: -#abstract states = 2#predicates build abstraction during search -exponential Thm Prover queries Don’t Refine Error-Free Regions

Error Free

Problem: Solution: -#abstract states = 2#predicates Refine only spurious -exponential Thm Prover queries counterexamples Putting It Together: Lazy Abstraction

Initial 1 Unroll abstraction 1. Pick tree node (= abs. state) 2 2. Add children (= abs. successors) 3. On revisiting abs. state, cut off 3

4 5 Find min. spurious suffix - learn new predicates

3 - rebuild subtree with new predicates

Abstract Reachability Tree [Henzinger-Jhala-Majumdar-Sutre 03: BLAST] Putting It Together: Lazy Abstraction

Initial 1 Unroll abstraction 1. Pick tree node (= abs. state) 2 2. Add children (= abs. successors) 3. On revisiting abs. state, cut off 3 6

4 5 7 Find min. spurious suffix - learn new predicates 3 3 - rebuild subtree with new predicates

Error Free Putting It Together: Lazy Abstraction

Initial 1 Unroll abstraction 1. Pick tree node (= abs. state) 2 2. Add children (= abs. successors) 3. On revisiting abs. state, cut off 3 6

4 5 7 8 Find min. spurious suffix - learn new predicates 3 3 1 8 1 - rebuild subtree with new predicates

Error Free Only abstract reachable states SAFE Don’t refine error-free regions Abstract Interpretation

ExampleExample (( )) {{ 11:: do{do{ lock();lock(); old = new; old = new; 1 ¬ LOCK qq == q->next;q->next; 22:: ifif (q(q !=!= NULL){NULL){ 33:: q->dataq->data == new;new; unlock();unlock(); newnew ++;++; }} 44:}while(new:}while(new !=!= old);old); 55::unlock();unlock(); }}

1 Abstract Reachability Tree Predicates: LOCK Abstract Interpretation

ExampleExample (( )) {{ 11:: do{do{ lock();lock(); old = new; old = new; lock() 1 ¬ LOCK qq == q->next;q->next; 22:: ifif (q(q !=!= NULL){NULL){ old = new 3: q->data = new; 3: q->data = new; q=q->next 2 LOCK unlock();unlock(); newnew ++;++; }} 44:}while(new:}while(new !=!= old);old); 55:: unlockunlock ();(); }}

1 2 Abstract Reachability Tree Predicates: LOCK Abstract Interpretation

ExampleExample (( )) {{ 11:: do{do{ lock();lock(); old = new; old = new; 1 ¬ LOCK qq == q->next;q->next; 22:: ifif (q(q !=!= NULL){NULL){ 3: q->data = new; 3: q->data = new; 2 LOCK unlock();unlock(); [q!=NULL] newnew ++;++; }} 44:}while(new:}while(new !=!= old);old); 3 LOCK 55:: unlock();unlock(); }}

1 2 3 Abstract Reachability Tree Predicates: LOCK Abstract Interpretation

ExampleExample (( )) {{ 11:: do{do{ lock();lock(); old = new; old = new; 1 ¬ LOCK qq == q->next;q->next; 22:: ifif (q(q !=!= NULL){NULL){ 3: q->data = new; 3: q->data = new; 2 LOCK unlock();unlock(); newnew ++;++; }} 44:}while(new:}while(new !=!= old);old); q->data = new 3 LOCK 55:: unlock();unlock(); }} unlock() new++ 4 ¬ LOCK

4

1 2 3 Abstract Reachability Tree Predicates: LOCK Abstract Interpretation

ExampleExample (( )) {{ 11:: do{do{ lock();lock(); old = new; old = new; 1 ¬ LOCK qq == q->next;q->next; 22:: ifif (q(q !=!= NULL){NULL){ 3: q->data = new; 3: q->data = new; 2 LOCK unlock();unlock(); newnew ++;++; }} 44:}while(new:}while(new !=!= old);old); 3 LOCK 55:: unlock();unlock(); }} 4 ¬ LOCK [new==old] 5 ¬ LOCK 5

4

1 2 3 Abstract Reachability Tree Predicates: LOCK Abstract Interpretation

ExampleExample (( )) {{ 11:: do{do{ lock();lock(); old = new; old = new; 1 ¬ LOCK qq == q->next;q->next; 22:: ifif (q(q !=!= NULL){NULL){ 3: q->data = new; 3: q->data = new; 2 LOCK unlock();unlock(); newnew ++;++; }} 44:}while(new:}while(new !=!= old);old); 3 LOCK 55:: unlock();unlock(); }} 4 ¬ LOCK

5 ¬ LOCK 5 unlock()

4 ¬ LOCK 1 2 3 Abstract Reachability Tree Predicates: LOCK Analyze Counterexample

ExampleExample (( )) {{ 11:: do{do{ lock();lock(); old = new; old = new; 1 ¬ LOCK lock() qq == q->next;q->next; 22:: ifif (q(q !=!= NULL){NULL){ old = new 3: q->data = new; 3: q->data = new; 2 LOCK q=q->next unlock();unlock(); new ++; new ++; [q!=NULL] }} 44:}while(new:}while(new !=!= old);old); 3 LOCK q->data = new 55:: unlock();unlock(); }} unlock() new++ 4 ¬ LOCK [new==old] 5 ¬ LOCK 5 unlock()

4 ¬ LOCK 1 2 3 Abstract Reachability Tree Predicates: LOCK Analyze Counterexample

ExampleExample (( )) {{ 11:: do{do{ lock();lock(); old = new; old = new; 1 ¬ LOCK qq == q->next;q->next; 22:: ifif (q(q !=!= NULL){NULL){ old = new 3: q->data = new; 3: q->data = new; 2 LOCK unlock();unlock(); newnew ++;++; }} 44:}while(new:}while(new !=!= old);old); 3 LOCK 55:: unlock();unlock(); }} new++ 4 ¬ LOCK [new==old] 5 ¬ LOCK 5 Spurious 4 ¬ LOCK new = old 1 2 3 Abstract Reachability Tree Predicates: LOCK Refined Abstract Interpretation

ExampleExample (( )) {{ 11:: do{do{ lock();lock(); old = new; old = new; 1 ¬ LOCK qq == q->next;q->next; 22:: ifif (q(q !=!= NULL){NULL){ 33:: q->dataq->data == new;new; unlock();unlock(); newnew ++;++; }} 44:}while(new:}while(new !=!= old);old); 55:: unlock();unlock(); }}

1 Abstract Reachability Tree Predicates: LOCK, new=old Refined Abstract Interpretation

ExampleExample (( )) {{ 11:: do{do{ lock();lock(); old = new; old = new; 1 ¬ LOCK qq == q->next;q->next; 22:: ifif (q(q !=!= NULL){NULL){ lock() 33:: q->dataq->data == new;new; LOCK , new=old 2 old = new unlock();unlock(); q=q->next newnew ++;++; }} 44:}while(new:}while(new !=!= old);old); 55:: unlock();unlock(); }}

1 2 Abstract Reachability Tree Predicates: LOCK, new=old Refined Abstract Interpretation

ExampleExample (( )) {{ 11:: do{do{ lock();lock(); old = new; old = new; 1 ¬ LOCK qq == q->next;q->next; 22:: ifif (q(q !=!= NULL){NULL){ 3: q->data = new; 3: q->data = new; 2 unlock();unlock(); LOCK , new=old newnew ++;++; }} 44:}while(new:}while(new !=!= old);old); LOCK , new=old 3 55:: unlock();unlock(); q->data = new }} unlock() new++ ¬ LOCK , ¬ new = old 4

4 1 2 3 Abstract Reachability Tree Predicates: LOCK, new=old Refined Abstract Interpretation

ExampleExample (( )) {{ 11:: do{do{ lock();lock(); old = new; old = new; 1 ¬ LOCK qq == q->next;q->next; 22:: ifif (q(q !=!= NULL){NULL){ 33:: q->dataq->data == new;new; LOCK , new=old 2 unlock();unlock(); newnew ++;++; }} 44:}while(new:}while(new !=!= old);old); LOCK , new=old 3 55:: unlock();unlock(); }}

¬ LOCK , ¬ new = old 4

[new==old]

4 1 2 3 Abstract Reachability Tree Predicates: LOCK, new=old Refined Abstract Interpretation

ExampleExample (( )) {{ 11:: do{do{ lock();lock(); old = new; old = new; 1 ¬ LOCK qq == q->next;q->next; 22:: ifif (q(q !=!= NULL){NULL){ 33:: q->dataq->data == new;new; LOCK , new=old 2 unlock();unlock(); newnew ++;++; }} 44:}while(new:}while(new !=!= old);old); LOCK , new=old 3 55:: unlock();unlock(); }}

¬ LOCK , ¬ new = old 4 [new!=old] 1

¬ LOCK, 4 ¬ new = old 1 2 3 Abstract Reachability Tree Predicates: LOCK, new=old Refined Abstract Interpretation

ExampleExample (( )) {{ 11:: do{do{ lock();lock(); old = new; old = new; 1 ¬ LOCK qq == q->next;q->next; 22:: ifif (q(q !=!= NULL){NULL){ 33:: q->dataq->data == new;new; LOCK , new=old 2 unlock();unlock(); newnew ++;++; }} 44:}while(new:}while(new !=!= old);old); LOCK , new=old 3 SAFE 55:: unlock();unlock(); }}

¬ LOCK , ¬ new = old 4 4 LOCK , new=old

1 5 5 ¬ LOCK, 4 4 ¬ new = old ¬ LOCK , new=old 1 2 3 Abstract Reachability Tree Predicates: LOCK, new=old #Predicates Grows with Program Size

while(1){while(1){ T 1: if (p ) lock() ; 1: if (p11) lock() ; F if (p ) unlock() ; if (p11) unlock() ; Tracking lock not enough …… T 2: if (p ) lock() ; 2: if (p22) lock() ; if (p ) unlock() ; if (p22) unlock() ; …… n: if (p ) lock() ; n: if (pnn) lock() ; if (p ) unlock() ; if (pnn) unlock() ; }}

Problem:

p1,…,pn needed for verification #Reachable abstract states exponential #Predicates Grows with Program Size

¬ LOCK while(1){while(1){ 1: if (p ) lock() ; 1: if (p11) lock() ; LOCK, p1 ¬ LOCK, ¬ p1 if (p ) unlock() ; if (p11) unlock() ; ¬ LOCK, p ¬ LOCK, ¬ p …… 1 1 2: if (p ) lock() ; 2: if (p22) lock() ; if (p ) unlock() ; if (p22) unlock() ; ¬ LOCK …… p p 1 2 p ¬ p ¬ p p ¬ p ¬ p n: if (p ) lock() ; 1 2 1 2 1 2 n: if (pnn) lock() ; if (p ) unlock() ; if (pnn) unlock() ; }} 2n abstract states Problem:

p1,…,pn needed for verification #Reachable abstract states exponential Predicates useful Locally

¬ LOCK while(1){while(1){ 1: if (p ) lock() ; 1: if (p11) lock() ; LOCK , p1 ¬ LOCK, ¬ p1 p1 if (p ) unlock() ; if (p11) unlock() ; ¬ LOCK¬ ,LOC p K¬ LOCK ¬ LOCK , ¬ p …… 1 1 2: if (p ) lock() ; 2: if (p22) lock() ; p LOCK , p ¬ LOCK , ¬ p2 2 if (p ) unlock() ; 2 if (p22) unlock() ; …… ¬ LOCK n: if (p ) lock() ; n: if (pnn) lock() ; pn if (p ) unlock() ; if (pnn) unlock() ; }} 2n abstract states Solution: Use predicates only where needed Using counterexamples: Q1. Find predicates Q2. Find where predicates are needed Counterexample Trace

1: x = ctr 11:: xx == ctr;ctr; 22:: ctrctr= = ctrctr+ + 1;1; 2: ctr = ctr + 1 33:: yy == ctr;ctr; 3: y = ctr 4: if (x = i-1){ y = x +1 4: if (x = i-1){ 4: assume(x = i-1) 55:: ifif (y(y !=!= i){i){ ≠ ERROR:ERROR: }} 5: assume(y i) }} Build Trace Formula

1: x = ctr 1: x1 = ctr0 x1 = ctr0

2: ctr = ctr+1 2: ctr1 = ctr0+1 ∧ ctr1 = ctr0+ 1

3: y = ctr 3: y1 = ctr1 ∧ y1 = ctr1

4: assume(x=i-1) 4: assume(x1=i0-1) ∧ x1 = i0 - 1

5: assume(y≠i) 5: assume(y1≠i0) ∧ y1 ≠ i0

Trace SSA Trace Trace Formula

Trace is feasible ⇔ TF is satisfiable Which Predicate is Needed ?

Trace Trace Formula (TF)

1: x = ctr x1 = ctr0

2: ctr = ctr + 1 ∧ ctr1 = ctr0+ 1

3: y = ctr ∧ y1 = ctr1

4: assume(x = i-1) ∧ x1 = i0 - 1

5: assume(y ≠ i) ∧ y1 ≠ i0 Which Predicate is Needed ?

Trace Trace Formula (TF)

1: x = ctr x1 = ctr0

2: ctr = ctr + 1 ∧ ctr1 = ctr0+ 1

3: y = ctr ∧ y1 = ctr1

4: assume(x = i-1) ∧ x1 = i0 - 1

5: assume(y ≠ i) ∧ y1 ≠ i0

Relevant Information Predicate …

1. … after executing trace prefix … implied by TF prefix Which Predicate is Needed ?

Trace Trace Formula (TF)

1: x = ctr xx1 = ctr0

2: ctr = ctr + 1 ∧ ctr1 = ctr0+ 1

3: y = ctr ∧ y1 = ctr1

4: assume(x = i-1) ∧ xx1 = i0 - 1

5: assume(y ≠ i) ∧ y1 ≠ i0

Relevant Information Predicate …

1. … after executing trace prefix … implied by TF prefix

2. … has present values of variables … on common variables Which Predicate is Needed ?

Trace Trace Formula (TF)

1: x = ctr x1 = ctr0

2: ctr = ctr + 1 ∧ ctr1 = ctr0+ 1

3: y = ctr ∧ y1 = ctr1

4: assume(x = i-1) ∧ x1 = i0 - 1

5: assume(y ≠ i) ∧ y1 ≠ i0

Relevant Information Predicate …

1. … after executing trace prefix … implied by TF prefix

2. … has present values of variables … on common variables

3. … makes trace suffix infeasible … and TF suffix is unsatisfiable Predicate = Interpolant

Trace Trace Formula 1: x = ctr x = ctr 1 0 Predicate at 4: 2: ctr = ctr + 1 ctr ctr 1 y= x+1 ∧ 1 = 0+ ψ- 3: y = ctr y ctr ∧ 1 = 1 Interpolate Φ 4: assume(x = i-1) ∧ x1 = i0 - 1 + ψ y1 = x1 + 1

5: assume(y ≠ i) ∧ y1 ≠ i0

Craig Interpolant Predicate … … implied by TF prefix

Computable from … on common variables proof of unsatisfiability [Krajicek. Pudlak, McMillan] … and TF suffix is unsatisfiable Building Predicate Maps

Predicate Trace Trace Formula 2: x = ctr ψ- 1: x = ctr x1 = ctr0 Interpolate x1 = ctr0 2: ctr = ctr + 1 ctr ctr 1 ∧ 1 = 0+ ψ+

3: y = ctr ∧ y1 = ctr1

4: assume(x = i-1) ∧ x1 = i0 - 1

5: assume(y ≠ i) ∧ y1 ≠ i0

• Cut + interpolate at each point

•Predicate Map: pci → interpolant from cut i Building Predicate Maps

Predicate Map Trace Trace Formula 2: x = ctr 3: x = ctr-1

1: x = ctr x1 = ctr0 ψ- 2: ctr = ctr + 1 ∧ ctr1 = ctr0+ 1 Interpolate 3: y = ctr y ctr x1= ctr1-1 ∧ 1 = 1 ψ+ 4: assume(x = i-1) ∧ x1 = i0 - 1

5: assume(y ≠ i) ∧ y1 ≠ i0

• Cut + interpolate at each point

•Predicate Map: pci → interpolant from cut i Building Predicate Maps

Predicate Map Trace Trace Formula 2: x = ctr 3: x= ctr - 1 4: y= x + 1 1: x = ctr x1 = ctr0 2: ctr = ctr + 1 ∧ ctr = ctr + 1 1 0 ψ- 3: y = ctr ∧ y1 = ctr1 Interpolate 4: assume(x = i-1) ∧ x1 = i0 - 1 + y = x +1 ψ 1 1 5: assume(y ≠ i) ∧ y1 ≠ i0

• Cut + interpolate at each point

•Predicate Map: pci → interpolant from cut i Building Predicate Maps

Predicate Map Trace Trace Formula 2: x = ctr 3: x= ctr - 1 4: y= x + 1 1: x = ctr x1 = ctr0 5: y = i 2: ctr = ctr + 1 ∧ ctr1 = ctr0+ 1 3: y = ctr ∧ y ctr 1 = 1 ψ- 4: assume(x = i-1) ∧ x1 = i0 - 1 Interpolate 5: assume(y ≠ i) y ≠ i y = i ∧ 1 0 ψ+ 1 0 • Cut + interpolate at each point

•Predicate Map: pci → interpolant from cut i Local Predicate Use

Use predicates needed at location Predicate Map 2: x = ctr • #Preds grows with program size 3: x= ctr - 1 4: y= x + 1 •#Predicates per location small 5: y = i

Verification scales !

Local Predicate use Global Predicate use Ex: O(n) states Ex: 2n states Property 3: BLAST IRP Handler Win NT DDK

Program Lines* Non-lazy Lazy Time Predicates Time (mins) (mins) Total Average kbfiltr 12k 1 3726.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 Verification by Theorem Proving

ExampleExample ()() {{ 11:: do{do{ 1. Loop invariants lock();lock(); oldold == new;new; 2. Logical formula qq == q->next;q->next; 3. Check 22:: ifif (q(q !=!= NULL){NULL){ 33:: q->data q->data == new;new; unlock();unlock(); newnew ++;++; }} Invariant: 44:: }} while(newwhile(new!= != old);old); lock ∧ new = old 55:: unlock();unlock(); return;return; ∨ }} ¬ lock ∧ new ≠ old Verification by Theorem Proving

ExampleExample ()() {{ 11:: do{do{ 1. Loop invariants lock();lock(); oldold == new;new; 2. Logical formula qq == q->next;q->next; 3. Check validity 22:: ifif (q(q !=!= NULL){NULL){ 33:: q->data q->data == new;new; unlock();unlock(); newnew ++;++; } } - Loop invariants 44:: }} while(newwhile(new!= != old);old); 55:: unlock();unlock(); - Multithreaded programs return;return; + Behaviors encoded in }} + Decision procedures Precise [e.g. ESC] Verification by Program Analysis

ExampleExample ()() {{ 11:: do{do{ 1. Dataflow facts lock();lock(); oldold == new;new; 2. Constraint system qq == q->next;q->next; 3. Solve constraints 22:: ifif (q(q !=!= NULL){NULL){ 33:: q->data q->data == new;new; unlock();unlock(); newnew ++;++; }} 44:: }} while(newwhile(new!= != old);old); - Imprecision due to fixed facts 55:: unlock();unlock(); + Abstraction return;return; }} + Type/flow analyses Scalable [e.g. CQUAL, ESP, MC] Verification by Model Checking

ExampleExample ()() {{ 11:: do{do{ 1. (Finite State) Program lock();lock(); oldold == new;new; 2. State Transition Graph qq == q->next;q->next; 3. Reachability 22:: ifif (q(q !=!= NULL){NULL){ 33:: q->data q->data == new;new; unlock();unlock(); newnew ++;++; }} - Finite state model 44:: }} while(newwhile(new!= != old);old); - State explosion 55:: unlock();unlock(); return;return; + State exploration }} + Counterexamples Automatic [e.g. SPIN, Bandera, JPF ] Combining Strengths

Theorem Proving Program Analysis

-Imprecise -Loop invariants Lazy + Behaviors encoded in logic + Abstraction + Theorem provers Abstraction Shrink state space Computing successors; refine

Model Checking - Finite-state model, state explosion + State space exploration Path-sensitive analysis + Counterexamples Finding relevant facts Conclusions

-take the best of each technology: automatic, precise, scalable -verify programs, not models: verifying compiler -current research: concurrency, heap

http://mtc.epfl.ch/software-tools/blast joint with R. Jhala (UCSD) and R. Majumdar (UCLA)