Download presentation
Presentation is loading. Please wait.
1
Lazy Abstraction Thomas A. Henzinger Ranjit Jhala Rupak Majumdar Grégoire Sutre UC Berkeley
2
2 Motivation Verification of systems code Locking disciplines Interface specifications Essential for correct operation High rate of bugs Temporal properties Require path-sensitive analysis Swamped by false positives Really hard to check
3
3 Model Checking Doesn’t scale to low level implementations Can only model check “abstractions” Requires human intervention … Abstract – Check – Refine Loop Microsoft SLAM Project [Clarke et. al. 00], [Saidi 00]
4
4 Abstract-Check-Refine Loop Abstract Explanation YES (Trace) BUG Feasible ??? Check Refine NO SAFE Seed Abstraction Program Abstraction Infeasible Why infeasible ? Is model unsafe ?
5
5 Model Checking 101 ERROR STATES Init SYSTEM’S STATE SPACE Keep searching successors until … Hit error states: report “ bug ” ! Add no new successors: report “ safe ” Could take a long time …
6
6 Model Checking & Abstraction Problem: Far too many states Iterations don ’ t terminate ! Solution: Abstract … ERROR STATES Init
7
7 ERROR STATES Init Model Checking & Abstraction Problem: Abstraction too coarse Solution: Refine abstraction Make boxes smaller
8
8 ERROR STATES Init Model Checking & Abstraction Problem: Abstraction too coarse Solution: Refine abstraction Make boxes smaller
9
9 Abstract Only Where Required ERROR STATES Init Abstraction is very expensive Why abstract regions that are never visited ? Reachable States On-the-fly abstraction: driven by the search
10
10 Refine Only Where Required Why be precise everywhere ? Don ’ t refine error-free regions ERROR STATES Init ERROR FREE
11
11 Refine Only Where Required Why be precise everywhere ? Don ’ t refine error-free regions Different precision for different regions Local Refinement : driven by the search ERROR STATES Init ERROR FREE
12
12 How to improve Abstract only where required Reachable state space is very sparse Construct the abstraction on-the-fly Use greater precision only where required Different precisions/abstractions for different regions Refine locally Reuse work from earlier phases Batch-oriented ) lose work from previous runs Integrate the three phases Exploit control flow structure
13
13 Example Q: Is Error Reachable ? Example ( ) { 1: if (*) { 7: do { got_lock = 0; 8: if (*) { 9: lock(); got_lock ++; } 10: if (got_lock) { 11: unlock(); } 12: } while (*) ; } 2: do { lock(); old = new; 3: if (*) { 4: unlock(); new ++; } 5: } while ( new != old); 6: unlock (); return; } unlock()lock() unlock()
14
14 Example ( ) { 1: if (*) { 7: do { got_lock = 0; 8: if (*) { 9: lock(); got_lock ++; } 10: if (got_lock) { 11: unlock(); } 12: } while (*) ; } 2: do { lock(); old = new; 3: if (*) { 4: unlock(); new ++; } 5: } while ( new != old); 6: unlock (); return; } Example:CFA 1 3 lock(); old = new 2 7 [>][>][>][>] 4 5 [>][>] [>][>] unlock() new++ 6 [new==old] [new!=old] ret unlock()
15
15 Example ( ) { 1: if (*) { 7: do { got_lock = 0; 8: if (*) { 9: lock(); got_lock ++; } 10: if (got_lock) { 11: unlock(); } 12: } while (*) ; } 2: do { lock(); old = new; 3: if (*) { 4: unlock(); new ++; } 5: } while ( new != old); 6: unlock (); return; } Example:CFA 8 10 9 12 11 7 1 3 2 4 5 6 ret got_lock=0 [>][>] [>][>] lock(); got_lock++ [got_lock == 0] [got_lock != 0] unlock() [>][>] [>][>]
16
16 Example:CFA Q: Is Error Reachable ? Example ( ) { 1: if (*) { 7: do { got_lock = 0; 8: if (*) { 9: lock(); got_lock ++; } 10: if (got_lock) { 11: unlock(); } 12: } while (*) ; } 2: do { lock(); old = new; 3: if (*) { 4: unlock(); new ++; } 5: } while ( new != old); 6: unlock (); return; } 8 10 9 12 11 7 1 3 2 4 5 6 ret unlock()lock() unlock()
17
17 Step 1: Search Set of predicates: LOCK=0, LOCK=1 1 LOCK=0 2 4 LOCK=1 6 LOCK=0 [>][>] lock(); old = new [>][>] unlock() new++ [new==old] unlock() 8 10 9 12 11 7 1 3 2 4 5 6 ret 5 LOCK=0 3 LOCK=1 Err LOCK=0
18
18 Q: When can: Step 2: Analyze Counterexample 1 LOCK=0 2 3 LOCK=1 4 5 LOCK=0 6 Err LOCK=0 8 10 9 12 11 7 1 3 2 4 5 6 ret n Err ops States that can = wp( >,ops) States at node n = R n ) check: R n Æ wp( >,ops) = ? ?
19
19 Step 2: Analyze Counterexample 1 LOCK=0 2 3 LOCK=1 4 5 LOCK=0 6 Err LOCK=0 lock(); old = new [>][>] unlock(); new++ [new==old] unlock() LOCK=0 LOCK=0 Æ new = old LOCK=0 Æ new+1 = new LOCK=1 Æ new+1 = old 8 10 9 12 11 7 1 3 2 4 5 6 ret R n Æ wp (>,ops) = ? ?
20
20 Step 2: Analyze Counterexample 1 LOCK=0 2 3 LOCK=1 4 5 LOCK=0 6 Err LOCK=0 lock(); old = new [>][>] unlock(); new++ [new==old] unlock() LOCK=0 LOCK=0 Æ new = old LOCK=0 Æ new+1 = new LOCK=1 Æ new+1 = old 8 10 9 12 11 7 1 3 2 4 5 6 ret Track the predicate: new = old
21
21 Step 3: Resume search 1 LOCK=0 2 4 LOCK=1 Æ new = old lock(); old = new [>][>] unlock() new++ [new==old] ? 6 [new!=old] 2 LOCK=0 Æ : new = old µ LOCK =0 Set of predicates: LOCK=0, LOCK=1 New predicate: new = old, 8 10 9 12 11 7 1 3 2 4 5 6 ret 5 LOCK=0 Æ : new = old 3 LOCK=1 Æ new = old
22
22 Step 3: Resume search 1 LOCK=0 2 3 LOCK=1 Æ new = old 4 5 LOCK=0 Æ : new = old ? 62 LOCK=0 Æ : new = old [>][>] 5 LOCK=1 Æ new=old 6 [new==old] [new!=old] 1 ? unlock() 8 10 9 12 11 7 1 3 2 4 5 6 ret Set of predicates: LOCK=0, LOCK=1 New predicate: new = old ret LOCK=0Æ new=old
23
23 Example ( ) { 1: if (*) { 7: do { got_lock = 0; 8: if (*) { 9: lock(); got_lock ++; } 10: if (got_lock) { 11: unlock(); } 12: } while (*) ; } 2: do { lock(); old = new; 3: if (*) { 4: unlock(); new ++; } 5: } while ( new != old); 6: unlock (); return; } Example:CFA 8 10 9 12 11 7 1 3 2 4 5 6 ret got_lock=0 [>][>] [>][>] lock(); got_lock++ [got_lock == 0] [got_lock != 0] unlock() [>][>] [>][>]
24
24 Step 4: Search Right Branch 1 LOCK=0 [>][>] 2 7 [>][>] Err 8 10 9 12 11 7 1 3 2 4 5 6 ret Set of predicates: LOCK=0, LOCK=1 New predicate: (from trace) got_lock = 0
25
25 Leaves Covered (Reuse work) 1 LOCK=0 2 7 2 2 2 LOCK=0 Æ … COVERED ! Leaves covered: Avoid repeating search when paths merge 8 10 9 12 11 7 1 3 2 4 5 6 ret
26
26 Different Abstractions 1 2 7 got_lock = 0new = old Different predicates for different parts of state space Local refinement: Preserves work on left tree 8 10 9 12 11 7 1 3 2 4 5 6 ret
27
27 Predicate Discovery Information lost in substitution Keep substitutions explicit Ask a proof of unsatisfiability Pick predicates appearing in proof 2 LOCK=0 3 LOCK=1 4 5 LOCK=0 6 Err LOCK=0 lock(); old = new [>][>] unlock(); new++ [new==old] unlock() LOCK=0 Æ new+1 = new
28
28 New Predicates from proof of unsatisfiability old’ = new, new’ = old’, new’ = new + 1 Predicate Discovery Weakest Precondition: wp( , x=e) ´ [e/x] Explicit WP: wp( , x=e) ´ 9 x’. x’ = e Æ [x’/x] LOCK = 0 Æ 9 old’ new’ LOCK’. old’ = new Æ LOCK’=0 Æ new’ = old’ Æ new’ = new’ + 1 2 LOCK=0 3 LOCK=1 4 5 LOCK=0 6 Err LOCK=0 lock(); old = new [>][>] unlock(); new++ [new==old] unlock() LOCK=0 Æ new+1 = new
29
29 Lazy abstraction For any system, require: Region representation Boolean operations: [, Å, : “Covering” check: µ post # : Region ! Approx. succ. Region Forward Search pre: Region ! Exact pred. Region Backward counterexample analysis focus : why a trace is infeasible
30
30 BLAST LAZY ABSTRACTION Berkeley Lazy Abstraction Software verification Tool 10K Lines of Ocaml Analyze Linux/Windows Device Drivers CIL (C ! CFA) REGION STRUCTURE BDD Engine (Boolean ops) Simplify (Post # ) Vampyre (focus)
31
31 Experiments [Not in POPL paper] Linux Device Drivers (Locking protocol) Windows Drivers (IRP Spec – 22 states) ProgramLinesPredicatesTime ide.c 181312295 ½ min aironet.c 1815217114 min aha152x.c 177366642 sec ProgramLinesPredicatesTime floppy.c 173861005121 min kbfiltr.c 1213112810 sec
32
32 Why Abstract Lazily ? Reach set is very sparse Abstract on-the-fly Only the reachable region Requires very fast post # Exploit Control-Flow Structure Free partitioning of state space Partition preds: different abstractions Refine locally: don ’ t repeat old work
33
33 Problems/Future work Monolithic vs. Multi-model abstractions How to partition predicates ? Predicate-flow analyses ? Recursion Summaries tricky with on-the-fly search Smarter abstractions Heap data structures ?
34
34 Predicate Abstraction P 1 : x = y P 3 : x z+1 P 2 : z = t + y P 4 : * u = x Karnaugh Map :P1,:P2:P1,:P2 P 1, P 2 P 1, : P 2 : P 1, P 2 :P3:P4:P3:P4 :P3P4:P3P4 P3P4P3P4 P3:P4P3:P4 Set of states Abstract Set: P 1 P 2 P 4 Ç : P 1 P 2 P 3 P 4 Region Representation: formulas over predicates
35
35 Predicate Abstraction Box: abstract variable valuation BoxCover(S): Set of boxes covering S Theorem prover used to compute BoxCover P 1 : x = y P 3 : x z+1 P 2 : z = t + y P 4 : * u = x Karnaugh Map :P1,:P2:P1,:P2 P 1, P 2 P 1, : P 2 : P 1, P 2 :P3:P4:P3:P4 :P3P4:P3P4 P3P4P3P4 P3:P4P3:P4
36
36 Post #, Pre pre(S,op) = { s | 9 s ’ 2 S. s ! op s ’ } ( Weakest Precondition ) post(S,op) = { s | 9 s ’ 2 S. s ’ ! op s} ( Strongest Postcondition ) Abstract Operators: post # post(S,op) µ post # (S,op) Concrete Operators: pre Classical Weakest Precondition :P1,:P2:P1,:P2 P 1, P 2 P 1, : P 2 : P 1, P 2 :P3:P4:P3:P4 :P3P4:P3P4 P3P4P3P4 P3:P4P3:P4 S post post(S) post # (S)
37
37 Predicate Abstraction in SLAM Abstraction: Boolean Programs (C2BP) Boolean variable for each predicate C program Boolean program Model checker: Bebop Refine: Newton Extracts new predicates from error trace Start afresh with new abstraction Can we do better ? Reuse work from earlier phases Abstract only where required Use additional predicates only where required Abstract Check Refine
38
38 Example ( ) { 1: if (*) { 7: do { got_lock = 0; 8: if (*) { 9: lock(); got_lock ++; } 10: if (got_lock) { 11: unlock(); } 12: } while (*) ; } 2: do { lock(); old = new; 3: if (*) { 4: unlock(); new ++; } 5: } while ( new != old); 6: unlock (); return; } Example Unrelated Code: Critical Sections etc.
39
39 Example: Specification lock (){ if (LOCK == 0){ LOCK = 1; } else { ERROR } unlock (){ if (LOCK == 1){ LOCK = 0; } else { ERROR } Q: Is Error Reachable ? Example ( ) { 1: if (*) { 7: do { got_lock = 0; 8: if (*) { 9: lock(); got_lock ++; } 10: if (got_lock) { 11: unlock(); } 12: } while (*) ; } 2: do { lock(); old = new; 3: if (*) { 4: unlock(); new ++; } 5: } while ( new != old); 6: unlock (); return; }
40
40 Example ( ) { 1: if (*) { 7: do { got_lock = 0; 8: if (*) { 9: lock(); got_lock ++; } 10: if (got_lock) { 11: unlock(); } 12: } while (*) ; } 2: do { lock(); old = new; 3: if (*) { 4: unlock(); new ++; } 5: } while ( new != old); 6: unlock (); return; } Example:CFA 8 10 9 12 11 7 1 3 2 4 5 6 ret got_lock=0 [>][>] [>][>] lock(); got_lock++ [get_lock == 0] [get_lock != 0] unlock() [>][>] [>][>]
41
41 Example:CFA 8 10 9 12 11 7 1 3 2 4 5 6 ret Q: Is Error Reachable ? lock (){ if (LOCK == 0){ LOCK = 1; } else { ERROR } unlock (){ if (LOCK == 1){ LOCK = 0; } else { ERROR } Example ( ) { 1: if (*) { 7: do { got_lock = 0; 8: if (*) { 9: lock(); got_lock ++; } 10: if (got_lock) { 11: unlock(); } 12: } while (*) ; } 2: do { lock(); old = new; 3: if (*) { 4: unlock(); new ++; } 5: } while ( new != old); 6: unlock (); return; } unlock()lock() unlock()
42
42 Model Checking Doesn’t scale to low level implementations Abstract – Check – Refine Loop Microsoft SLAM Project [Clarke et. al. 00], [Saidi 00] Abstraction is expensive ! Abstract only if/where required Different abstractions for different parts of system Reuse work from previous iterations Lazy abstraction: Short circuits the loop Avoids repeating work Abstractions computed locally, if/where required
43
43 Can We Do Better ? Abstract only where required Reachable state space is very sparse Use greater precision only where required Different precisions/abstractions for different regions Reuse work from earlier phases Batch-oriented ) lose work from previous runs Don ’ t repeat search in error-free regions
44
44 Our proposal Integrate the three phases Construct the abstraction on-the-fly Driven by the reachability search Refine the abstraction on demand Refine locally
45
45 Outline Motivation The verification loop An example The Lazy abstraction algorithm BLAST Conclusions
46
46 Outline Motivation The verification loop An example The Lazy abstraction algorithm BLAST Conclusions
47
47 Outline Motivation The verification loop An example The lazy abstraction algorithm For sequential code Blast Conclusions
48
48 Outline Motivation The verification loop An example The lazy abstraction algorithm For sequential code Blast Conclusions
49
49 1: Forward Search post # µ
50
50 2: Counterexample Analysis pre, Å
51
51 Untouched 3: Refine Refinement Focus
52
52 A complication Refinement Uncovered!
53
53 Model Checking & Abstraction Problem: Abstraction too coarse Solution: Refine abstraction Make boxes smaller
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.