Presentation is loading. Please wait.

Presentation is loading. Please wait.

Software Verification with BLAST Tom Henzinger Ranjit Jhala Rupak Majumdar.

Similar presentations


Presentation on theme: "Software Verification with BLAST Tom Henzinger Ranjit Jhala Rupak Majumdar."— Presentation transcript:

1 Software Verification with BLAST Tom Henzinger Ranjit Jhala Rupak Majumdar

2 Blast Web Site http://www.eecs.berkeley.edu/~blast

3 Software Validation Large scale reliable software is hard to build and test Different groups write different components Integration testing is a nightmare

4 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 ?

5 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

6 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 unlock

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

8 Property 3 : IRP Handler [Fahndrich] MPR3 CallDriver MPR completion synch not pending returned SKIP2 IPC CallDriver Skip return child status DC Complete request return not Pend PPC prop completion CallDriver N/A no prop completion CallDriver start NP return Pending NP MPR1 MPR completion SKIP2 IPC CallDriver DC Complete request PPC prop completion CallDriver N/A no prop completion CallDriver start P Mark Pending IRP accessible N/A synch SKIP1 CallDriver SKIP1 Skip MPR2 MPR1 NP MPR3 CallDriver not pending returned MPR2 synch

9 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!

10 Plan Motivation Lazy Abstraction Demo Technical Details

11 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 unlock

12 What a program really is… State Transition 3: unlock(); new++; 4:} … 3: unlock(); new++; 4:} … pc lock old new q  3   5  0x133a pc lock old new q  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;}

13 The Safety Verification Problem Initial Error Is there a path from an initial to an error state ? Problem: Infinite state graph Solution : Set of states ' logical formula Safe

14 Representing States as Formulas [F] states satisfying F {s | s ² F } F FO fmla over prog. vars [F 1 ] Å [F 2 ]F1 Æ F2F1 Æ F2 [F 1 ] [ [F 2 ]F 1 Ç F 2 [F][F] : F [F 1 ] µ [F 2 ]F 1 implies F 2 i.e. F 1 Æ: F 2 unsatisfiable

15 Idea 1: Predicate Abstraction Predicates on program state: lock old = new States satisfying same predicates are equivalent –Merged into one abstract state #abstract states is finite

16 Abstract States and Transitions State 3: unlock(); new++; 4:} … 3: unlock(); new++; 4:} … pc lock old new q  3   5  0x133a pc lock old new q  4   5  6  0x133a lock old=new : lock : old=new Theorem Prover

17 Abstraction State 3: unlock(); new++; 4:} … 3: unlock(); new++; 4:} … pc lock old new q  3   5  0x133a pc lock old new q  4   5  6  0x133a lock old=new : lock : old=new Theorem Prover Existential Lifting

18 Abstraction State 3: unlock(); new++; 4:} … 3: unlock(); new++; 4:} … pc lock old new q  3   5  0x133a pc lock old new q  4   5  6  0x133a lock old=new : lock : old=new

19 Analyze Abstraction Analyze finite graph Over Approximate: Safe ) System Safe No false negatives Problem Spurious counterexamples

20 Idea 2: Counterex.-Guided Refinement Solution Use spurious counterexamples to refine abstraction !

21 1. Add predicates to distinguish states across cut 2. Build refined abstraction Solution Use spurious counterexamples to refine abstraction Idea 2: Counterex.-Guided Refinement Imprecision due to merge

22 Iterative Abstraction-Refinement 1. Add predicates to distinguish states across cut 2. Build refined abstraction -eliminates counterexample 3. Repeat search Till real counterexample or system proved safe Solution Use spurious counterexamples to refine abstraction [Kurshan et al 93] [Clarke et al 00] [Ball-Rajamani 01]

23 Lazy Abstraction Abstract Refine C Program Safe Trace Yes No Property BLAST

24 Lazy Abstraction C Program Safe Trace Yes No Property BLAST spec.opt Instrumented C file With ERROR label

25 Problem: Abstraction is Expensive Reachable Problem #abstract states = 2 #predicates Exponential Thm. Prover queries Observe Fraction of state space reachable #Preds ~ 100’s, #States ~ 2 100, #Reach ~ 1000’s

26 Safe Solution Build abstraction during search Problem #abstract states = 2 #predicates Exponential Thm. Prover queries Solution1 : Only Abstract Reachable States

27 Solution Don’t refine error-free regions Problem #abstract states = 2 #predicates Exponential Thm. Prover queries Solution2: Don’t Refine Error-Free Regions Error Free

28 Key Idea: Reachability Tree 5 1 2 3 4 3 Unroll Abstraction 1. 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

29 Key Idea: Reachability Tree 3 1 2 3 4 5 3 7 6 Error Free Unroll Abstraction 1. 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

30 Key Idea: Reachability Tree 3 1 2 3 4 5 3 6 Error Free 7 1 8 8 1 SAFE Unroll 1. 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

31 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

32 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 LOCK 2 2 Reachability Tree

33 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 2 2 [q!=NULL] 3 3 Reachability Tree

34 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 2 2 3 3 q ->data = new unlock() new++ 4 4 : LOCK Reachability Tree

35 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 2 2 3 3 4 4 : LOCK [new==old] 5 5 Reachability Tree

36 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 2 2 3 3 4 4 : LOCK 5 5 unlock() : LOCK Reachability Tree

37 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 LOCK 2 2 3 3 4 4 : LOCK 5 5 Reachability Tree lock() old = new q=q->next [q!=NULL] q ->data = new unlock() new++ [new==old] unlock()

38 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 LOCK 2 2 3 3 4 4 : LOCK 5 5 [new==old] new++ old = new Inconsistent new == old Reachability Tree

39 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

40 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

41 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 3 3 4 4 q ->data = new unlock() new++ : LOCK, : new = old Reachability Tree

42 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 3 3 4 4 : LOCK, : new = old [new==old] Reachability Tree

43 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 3 3 4 4 : LOCK, : new = old : LOCK, : new == old 1 [new!=old] 4 Reachability Tree

44 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 5 5 SAFE Reachability Tree LOCK, new==old : LOCK, : new = old : LOCK, : new == old

45 Key Idea: Reachability Tree 3 1 2 3 4 5 3 6 Error Free 7 1 8 8 1 SAFE Unroll 1. 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

46 Lazy Abstraction Abstract Refine C Program Safe Trace Yes No Property Key Idea: Reachability Tree Solution: 1. Abstract reachable states, 2. Avoid refining error-free regions Problem: Abstraction is Expensive

47 Plan Motivation Lazy Abstraction Demo Technical Details

48 Demo

49 Plan Motivation Lazy Abstraction Demo Technical Details

50 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 5 5 SAFE Reachability Tree LOCK, new==old : LOCK, : new = old : LOCK, : new == old

51 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 5 5 SAFE Reachability Tree 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” ?

52 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 5 5 SAFE LOCK, new==old : LOCK, : new = old : LOCK, : new == old Q. How to find predicates ? Q. How to compute “successors” ? Predicates: LOCK, new==old Refinement

53 Plan Motivation Lazy Abstraction Demo Technical Details –Q: How to compute “successors” ? –Q: How to find predicates ?

54 Plan Motivation Lazy Abstraction Demo Technical Details –Q: How to compute “successors” ? –Q: How to find predicates ? –Q: How to analyze (recursive) procedures ?

55 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 ?

56 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 5 5 SAFE LOCK, new==old : LOCK, : new = old : LOCK, : new == old Q. How to compute “successors” ?

57 Weakest Preconditions [P][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

58 Weakest Preconditions [P][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 = ex = e P P[e/x] new = old new = new+1 new+1 = old

59 Weakest Preconditions P c ) P new = old new=old ) new=old [c] Branch Assume [new=old] [P][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

60 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 ?

61 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 ?

62 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 ?

63 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 ?

64 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 5 5 SAFE LOCK, new==old : LOCK, : new = old : LOCK, : new == old Q. How to find predicates ?

65 Tracking lock not enough #Predicates grows with program size Problem: p 1,…,p n needed for verification Exponential reachable abstract states while(1){ 1: if (p 1 ) lock() ; if (p 1 ) unlock() ; … 2: if (p 2 ) lock() ; if (p 2 ) unlock() ; … n: if (p n ) lock() ; if (p n ) unlock() ; } while(1){ 1: if (p 1 ) lock() ; if (p 1 ) unlock() ; … 2: if (p 2 ) lock() ; if (p 2 ) unlock() ; … n: if (p n ) lock() ; if (p n ) unlock() ; } TFTTFT

66 #Predicates grows with program size Problem: p 1,…,p n needed for verification Exponential reachable abstract states while(1){ 1: if (p 1 ) lock() ; if (p 1 ) unlock() ; … 2: if (p 2 ) lock() ; if (p 2 ) unlock() ; … n: if (p n ) lock() ; if (p n ) unlock() ; } while(1){ 1: if (p 1 ) lock() ; if (p 1 ) unlock() ; … 2: if (p 2 ) lock() ; if (p 2 ) unlock() ; … n: if (p n ) lock() ; if (p n ) unlock() ; } : LOCK : LOCK, p 1 p1p2p1p2 p 1 : p 2 : p 1 p 2 : p 1 : p 2 LOCK, p 1 : LOCK, : p 1 2 n Abstract States : LOCK

67 Predicates useful locally while(1){ 1: if (p 1 ) lock() ; if (p 1 ) unlock() ; … 2: if (p 2 ) lock() ; if (p 2 ) unlock() ; … n: if (p n ) lock() ; if (p n ) unlock() ; } while(1){ 1: if (p 1 ) lock() ; if (p 1 ) unlock() ; … 2: if (p 2 ) lock() ; if (p 2 ) unlock() ; … n: if (p n ) lock() ; if (p n ) unlock() ; } : LOCK : LOCK, p 1 LOCK, p 1 : LOCK, : p 1 2n Abstract States p1p1 p2p2 pnpn : LOCK LOCK, p 2 : LOCK, : p 2 : LOCK Solution: Use predicates only where needed Using Counterexamples: Q1. Find predicates Q2. Find where predicates are needed

68 Lazy Abstraction Abstract Refine C Program Safe Trace Yes No Property Refine Pred. Map PC  Preds. Ctrex. Trace Solution: Localize pred. use, find where preds. needed Problem: #Preds grows w/ Program Size

69 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: } }

70 Trace Formulas 1: x = ctr 2: ctr = ctr+1 3: y = ctr 4: assume(x=i-1) 5: assume(y  i) Trace SSA Trace x 1 = ctr 0 Æ ctr 1 = ctr 0 + 1 Æ y 1 = ctr 1 Æ x 1 = i 0 - 1 Æ y 1  i 0 1: x 1 = ctr 0 2: ctr 1 = ctr 0 +1 3: y 1 = ctr 1 4: assume(x 1 =i 0 -1) 5: assume(y 1  i 0 ) Trace Feasibility Formula Thm: Trace is feasible, TF is satisfiable

71 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 pc 4, which predicate on present state shows infeasibility of future ?

72 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) x 1 = ctr 0 Æ ctr 1 = ctr 0 + 1 Æ y 1 = ctr 1 Æ x 1 = i 0 - 1 Æ y 1  i 0

73 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) x 1 = ctr 0 Æ ctr 1 = ctr 0 + 1 Æ y 1 = ctr 1 Æ x 1 = i 0 - 1 Æ y 1  i 0 1. … after executing trace prefix Relevant Information … implied by TF prefix Predicate …

74 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) x 1 = ctr 0 Æ ctr 1 = ctr 0 + 1 Æ y 1 = ctr 1 Æ x 1 = i 0 - 1 Æ y 1  i 0 … implied by TF prefix … on common variables Predicate … x1x1 x1x1 Relevant Information

75 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) x 1 = ctr 0 Æ ctr 1 = ctr 0 + 1 Æ y 1 = ctr 1 Æ x 1 = i 0 - 1 Æ y 1  i 0 … implied by TF prefix … on common variables … & TF suffix is unsatisfiable Predicate …Relevant Information

76 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) x 1 = ctr 0 Æ ctr 1 = ctr 0 + 1 Æ y 1 = ctr 1 Æ x 1 = i 0 - 1 Æ y 1  i 0 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

77 Interpolant = Predicate ! -- ++ Interpolate  Trace Formula x 1 = ctr 0 Æ ctr 1 = ctr 0 + 1 Æ y 1 = ctr 1 Æ x 1 = i 0 - 1 Æ y 1  i 0 y 1 = x 1 + 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

78 Another interpretation … -- ++ Interpolate  Trace Formula x 1 = ctr 0 Æ ctr 1 = ctr 0 + 1 Æ y 1 = ctr 1 Æ x 1 = i 0 - 1 Æ y 1  i 0 y 1 = x 1 + 1 Unsat = Empty Intersection = Trace Infeasible Predicate at 4: y= x+1 -- ++ After exec prefix Can exec suffix  Interpolant  = Overapprox. states after prefix that cannot execute suffix

79 Interpolant = Predicate ! -- ++ Interpolate  Trace Formula x 1 = ctr 0 Æ ctr 1 = ctr 0 + 1 Æ y 1 = ctr 1 Æ x 1 = i 0 - 1 Æ y 1  i 0 y 1 = x 1 + 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

80 Interpolant = Predicate ! -- ++ Interpolate  Trace Formula x 1 = ctr 0 Æ ctr 1 = ctr 0 + 1 Æ y 1 = ctr 1 Æ x 1 = i 0 - 1 Æ y 1  i 0 y 1 = x 1 + 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 ? …

81 Building Predicate Maps TraceTrace Formula x 1 = ctr 0 Æ ctr 1 = ctr 0 + 1 Æ y 1 = ctr 1 Æ x 1 = i 0 - 1 Æ y 1  i 0 Cut + Interpolate at each point Pred. Map: pc i  Interpolant from cut i -- ++ x 1 = ctr 0 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

82 Building Predicate Maps TraceTrace Formula x 1 = ctr 0 Æ ctr 1 = ctr 0 + 1 Æ y 1 = ctr 1 Æ x 1 = i 0 - 1 Æ y 1  i 0 -- ++ 1: x = ctr 2: ctr = ctr + 1 3: y = ctr 4: assume(x = i-1) 5: assume(y  i) Predicate Map 2: x = ctr 3: x= ctr-1 x 1 = ctr 1 -1 Interpolate Cut + Interpolate at each point Pred. Map: pc i  Interpolant from cut i

83 Building Predicate Maps TraceTrace Formula x 1 = ctr 0 Æ ctr 1 = ctr 0 + 1 Æ y 1 = ctr 1 Æ x 1 = i 0 - 1 Æ y 1  i 0 1: x = ctr 2: ctr = ctr + 1 3: y = ctr 4: assume(x = i-1) 5: assume(y  i) Predicate Map 2: x = ctr 3: x= ctr - 1 4: y= x + 1 y 1 = x 1 +1 -- ++ Interpolate Cut + Interpolate at each point Pred. Map: pc i  Interpolant from cut i

84 Building Predicate Maps TraceTrace Formula x 1 = ctr 0 Æ ctr 1 = ctr 0 + 1 Æ y 1 = ctr 1 Æ x 1 = i 0 - 1 Æ y 1  i 0 1: x = ctr 2: ctr = ctr + 1 3: y = ctr 4: assume(x = i-1) 5: assume(y  i) Predicate Map 2: x = ctr 3: x= ctr - 1 4: y= x + 1 5: y = i y 1 = i 0 -- ++ Interpolate Cut + Interpolate at each point Pred. Map: pc i  Interpolant from cut i

85 Local Predicate Use Predicate Map 2: x = ctr 3: x= ctr - 1 4: y= x + 1 5: 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: 2 n states Verification scales …

86 Localizing Program Lines * Previous Time(mins) Time (mins) Predicates Total Average kbfiltr 12k13726.5 floppy 17k7252407.7 diskprf 14k51314010 cdaudio 18k20232567.8 parport 61kDNF747538.1 parclss 138kDNF773827.2 * Pre-processed Property3: IRP Handler Win NT DDK

87 Lazy Abstraction Abstract Refine C Program Safe Trace Yes No Property Refine Trace Feas Formula Thm Pvr Proof of Unsat Pred. Map PC  Preds. Ctrex. Trace Interpolate Solution: Localize pred. use, find where preds. needed Problem: #Preds grows w/ Program Size

88 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

89 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 ?

90 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 5 5 SAFE LOCK, new==old : LOCK, : new = old : LOCK, : new == old Q. How to analyze recursive procedures ?

91 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; }

92 Inline Calls in Reach Tree 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; } 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

93 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; //global f1(){ 1: x = 0; 2: if(*) f2(); 3: else f2(); 4: if (x<0) ERROR; return; } int x; //global f1(){ 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; } 2 n nodes in Reach Tree

94 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!

95 Solution : Procedure Summaries Summaries: 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

96 Solution : Procedure Summaries Summaries: 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 ?

97 Lazy Abstraction + Procedure Summaries Abstract Refine C Program Safe Trace Yes No Property Q. How to compute, use summaries ?

98 Abstraction with Summaries 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; } 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]

99 Abstraction with Summaries 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; } 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=0 rv=a+1 rv>a Summary: ( : sign=0  rv>a),

100 Summary Successor 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; } 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>x assume rv>a y=rv

101 Abstraction with Summaries 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; } 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 y>x [y<=x] 3 4 flag=0 a=z sign=flag sign=0 [sign=0] [flag==0]

102 Abstraction with Summaries 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; } 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) 3 y>x 3 4 flag=0 a=z sign=flag sign=0 1 2 3 4 rv<a

103 Summary Successor 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; } 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) 3 y>x 3 4 flag=0 1 sign=0 2 3 4 rv<a a=x sign=flag assume rv<a y=rv 3 y<z

104 Abstraction with Summaries 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; } 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) 3 y>x 3 4 flag=0 1 sign=0 2 3 4 rv<a 3 y<z [y>=z]

105 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 3 4 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 z1 sign=0, rv>a, rv<a

106 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 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 3 4 flag=0 1 sign=0 2 3 4 rv<a 3 y<z 7 a=z1 sign=1 assume rv>a y1=rv 6 y1>z1 SAFE

107 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 ?

108 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 5 5 SAFE LOCK, new==old : LOCK, : new = old : LOCK, : new == old Q. How to analyze long traces ?

109 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

110 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?

111 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 = 0 1 i = 1 2 i ¸ 1000 2’ 3 c = c + f(i);i++ 4 2’ i<1000 a>0 x==0 5 1 4 a>0 x==0 5

112 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, and 2.feasible, then the last location of  is reachable (but not necessarily along  )

113 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

114 Example c = 0 1 i = 1 2 i ¸ 1000 2’ 3 c = c + f(i);i++ 4 2’ i<1000 a>0 x==0 5 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 current node to the step location on which a live variable is modified, or (2) the current node does not post-dominate the step location

115 Conditionals current step X = …  x 2 Live current step 

116 Example c = 0 1 i = 1 2 i ¸ 1000 2’ 3 c = c + f(i);i++ 4 2’ i<1000 a>0 x==0 5 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 current node to the step location on which a live variable is modified, or (2) the current node does not post-dominate the step location

117 Example c = 0 1 i = 1 2 i ¸ 1000 2’ 3 c = c + f(i);i++ 4 2’ i<1000 a>0 x==0 5 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: ; }

118 Example c = 0 1 i = 1 2 i ¸ 1000 2’ 3 c = c + f(i);i++ 4 2’ i<1000 a>0 x==0 5 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}

119 Example c = 0 1 i = 1 2 i ¸ 1000 2’ 3 c = c + f(i);i++ 4 2’ i<1000 a>0 x==0 5 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} An assignment is taken if the assigned variable is in the Live set

120 Example c = 0 1 i = 1 2 i ¸ 1000 2’ 3 c = c + f(i);i++ 4 2’ i<1000 a>0 x==0 5 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}

121 Slice 1 4 a>0 x==0 5 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: ; }

122 Example 2: Infeasible Path 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: ; } c = 0 1 i = 1 2 i ¸ 1000 2’ 3 c=c+f(i);i+ + 4 2’ i<1000 a>0 x==0 5 ERR, {} 5, {x} 4, {x, a}

123 Example 2: Infeasible Path 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: ; } c = 0 1 i = 1 2 i ¸ 1000 2’ 3 c = c + f(i);i++ 4 2’ i<1000 a>0 x==0 5 ERR, {} 5, {x} 4, {x, a} A B B, {a} x = 1 a>0 Live = (Live n Wr(op)) [ Rd(op) A, {a}

124 Slice 1 4 a>0 x==0 5 A B x = 1 a>0 Infeasible Slice implies 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: ; }

125 Lazy Abstraction: Summary Abstract Refine C Program Safe Trace Yes No Property Path Slice

126 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 details Proof of unsat of TF + Interpolation

127 Verification by Theorem Proving 1. Loop Invariants 2. Logical formula 3. 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; }

128 Verification by Theorem Proving 1. Loop Invariants 2. Logical formula 3. 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; } Precise [ESC]

129 Verification by Program Analysis 1. Dataflow Facts 2. Constraint System 3. 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 Analyses Scalable [CQUAL, ESP, MC]

130 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 + Counterexamples Precise [SPIN, SMV, Bandera,JPF ]

131 Combining Strengths Theorem Proving - loop invariants + Behaviors encoded in logic Refine + Theorem provers Computing Successors,Refine Program Analysis - Imprecise + Abstraction Shrink state space Model Checking - Finite-state model, state explosion + State Space Exploration Path Sensitive Analysis + Counterexamples Finding Relevant Facts Lazy Abstraction

132 Thank you http://www.eecs.berkeley.edu/~blast


Download ppt "Software Verification with BLAST Tom Henzinger Ranjit Jhala Rupak Majumdar."

Similar presentations


Ads by Google