Lazy Abstraction Lazy Abstraction Thomas A. Henzinger Ranjit Jhala Rupak Majumdar Grégoire Sutre UC Berkeley
Mar 18, 2016
Lazy AbstractionLazy AbstractionThomas A. Henzinger
Ranjit JhalaRupak MajumdarGrégoire Sutre
UC Berkeley
2
MotivationMotivationVerification of systems code
Locking disciplinesInterface specifications
Essential for correct operationHigh rate of bugs
Temporal propertiesRequire path-sensitive analysisSwamped by false positives
Really hard to check
3
Model CheckingModel CheckingDoesn’t scale to low level implementations
Can only model check “abstractions”
Requires human intervention …
Abstract – Check – Refine LoopMicrosoft SLAM Project[Clarke et. al. 00], [Saidi 00]
4
Abstract-Check-Refine LoopAbstract-Check-Refine Loop
Abstract
Explanation
YES (Trace)
BUG
Feasible
???
Check
Refine
NO
SAFE
Seed AbstractionProgram
Abstraction
InfeasibleWhy infeasible ?
Is model unsafe ?
5
Model Checking 101Model 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
Model Checking & AbstractionModel Checking & AbstractionProblem: Far too many states
Iterations don’t terminate !Solution: Abstract …
ERROR STATES
Init
7
ERROR STATES
Init
Model Checking & AbstractionModel Checking & AbstractionProblem: Abstraction too coarse
Solution: Refine abstractionMake boxes smaller
8
ERROR STATES
Init
Model Checking & AbstractionModel Checking & AbstractionProblem: Abstraction too coarse
Solution: Refine abstractionMake boxes smaller
9
Abstract Only Where RequiredAbstract 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
Refine Only Where RequiredRefine Only Where RequiredWhy be precise everywhere ?
Don’t refine error-free regions
ERROR STATES
Init
ERROR FREE
11
Refine Only Where RequiredRefine Only Where RequiredWhy 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
How to improve How to improve Abstract only where required
Reachable state space is very sparseConstruct the abstraction on-the-fly
Use greater precision only where requiredDifferent precisions/abstractions for different regionsRefine locally
Reuse work from earlier phasesBatch-oriented ) lose work from previous runsIntegrate the three phases
Exploit control flow structure
13
ExampleExample
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()
lock()
unlock()
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:CFAExample:CFA1
3
lock();old = new
2 7
[>][>]
4
5
[>]
[>]
unlock()new++
6
[new==old]
[new!=old]
retunlock()
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:CFAExample: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
Example:CFAExample: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
109
1211
7
1
3
2
45
6
retunlock() lock()
lock()
unlock()
17
Step 1: SearchStep 1: Search
Set of predicates: LOCK=0, LOCK=1
1 LOCK=0
2 LOCK=0
4 LOCK=1
6 LOCK=0
[>]
lock();old = new
[>]
unlock()new++
[new==old]
unlock()
8
109
1211
7
1
3
2
45
6
ret
5 LOCK=0
3 LOCK=1
Err LOCK=0
18
Q: When can:
Step 2:Step 2: Analyze CounterexampleAnalyze Counterexample1 LOCK=0
2 LOCK=0
3 LOCK=1
4 LOCK=1
5 LOCK=0
6 LOCK=0
Err LOCK=0
8
109
1211
7
1
3
2
45
6
ret
n Errops
States that can = wp( >,ops) States at node n = Rn
) check: Rn Æ wp( >,ops) = ? ?
19
Step 2:Step 2: Analyze CounterexampleAnalyze Counterexample1 LOCK=0
2 LOCK=0
3 LOCK=1
4 LOCK=1
5 LOCK=0
6 LOCK=0
Err LOCK=0
lock();old = new
[>]
unlock();new++
[new==old]
unlock()
LOCK=0
LOCK=0
LOCK=0 Æ new = old
LOCK=0 Æ new+1 = new
LOCK=1 Æ new+1 = old
LOCK=1 Æ new +1 = old
8
109
1211
7
1
3
2
45
6
ret
Rn Æ wp (>,ops) = ? ?
20
Step 2:Step 2: Analyze CounterexampleAnalyze Counterexample1 LOCK=0
2 LOCK=0
3 LOCK=1
4 LOCK=1
5 LOCK=0
6 LOCK=0
Err LOCK=0
lock();old = new
[>]
unlock();new++
[new==old]
unlock()
LOCK=0
LOCK=0
LOCK=0 Æ new = old
LOCK=0 Æ new+1 = new
LOCK=1 Æ new+1 = old
LOCK=1 Æ new +1 = old
8
109
1211
7
1
3
2
45
6
ret
Track the predicate:
new = old
21
Step 3: Resume searchStep 3: Resume search1LOCK=0
2LOCK=0
4LOCK=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
109
1211
7
1
3
2
45
6
ret
5LOCK=0 Æ : new = old
3LOCK=1 Æ new = old
22
Step 3: Resume searchStep 3: Resume search1LOCK=0
2LOCK=0
3LOCK=1 Æ new = old
4LOCK=1 Æ new = old
5LOCK=0 Æ : new = old
? 6 2
LOCK=0 Æ : new = old
[>]
5 LOCK=1 Æ new=old
6
[new==old][new!=old]
1
?unlock()
8
109
1211
7
1
3
2
45
6
ret
Set of predicates: LOCK=0, LOCK=1
New predicate: new = old
retLOCK=0Æ new=old
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:CFAExample: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
Step 4: Search Right BranchStep 4: Search Right Branch1 LOCK=0
[>]
2LOCK=0 7 LOCK=0
[>]
Err
8
109
1211
7
1
3
2
45
6
ret
Set of predicates: LOCK=0, LOCK=1
New predicate: (from trace) got_lock = 0
25
Leaves Covered (Reuse work)Leaves Covered (Reuse work)1 LOCK=0
2LOCK=0 7 LOCK=0
222
LOCK=0 Æ …COVERED !
Leaves covered:
Avoid repeating search when paths merge
8
109
1211
7
1
3
2
45
6
ret
26
Different AbstractionsDifferent Abstractions1
2 7
got_lock = 0new = old
Different predicates for
different parts of state space
Local refinement:
Preserves work on left tree
8
109
1211
7
1
3
2
45
6
ret
27
Predicate DiscoveryPredicate 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 LOCK=1
5 LOCK=0
6 LOCK=0
Err LOCK=0
lock();old = new
[>]
unlock();new++
[new==old]
unlock()
LOCK=0 Æ new+1 = new
28
New Predicates from proof of unsatisfiability
old’ = new, new’ = old’, new’ = new + 1
Predicate DiscoveryPredicate 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 LOCK=1
5 LOCK=0
6 LOCK=0
Err LOCK=0
lock();old = new
[>]
unlock();new++
[new==old]
unlock()
LOCK=0 Æ new+1 = new
29
Lazy abstraction Lazy abstraction For any system, require:
Region representationBoolean operations: [, Å, :“Covering” check: µ
post#: Region ! Approx. succ. RegionForward Search
pre: Region ! Exact pred. RegionBackward counterexample analysis
focus : why a trace is infeasible
30
BLASTBLAST
LAZY ABSTRACTION
Berkeley Lazy Abstraction Software verification Tool10K Lines of OcamlAnalyze Linux/Windows Device Drivers
CIL(C ! CFA)
REGION STRUCTURE
BDD Engine(Boolean ops)
Simplify
(Post#)
Vampyre(focus)
31
Experiments Experiments [Not in POPL paper][Not in POPL paper]Linux Device Drivers (Locking protocol)
Windows Drivers (IRP Spec – 22 states)
Program Lines Predicates Timeide.c 18131 22 9 5 ½ min
aironet.c 18152 17 11 4 min
aha152x.c 17736 6 6 42 sec
Program Lines Predicates Timefloppy.c 17386 100 51 21 min
kbfiltr.c 12131 12 8 10 sec
32
Why Abstract Lazily ?Why Abstract Lazily ?Reach set is very sparse
Abstract on-the-flyOnly the reachable regionRequires very fast post#
Exploit Control-Flow StructureFree partitioning of state spacePartition preds: different abstractionsRefine locally: don’t repeat old work
33
Problems/Future workProblems/Future workMonolithic vs. Multi-model abstractions
How to partition predicates ?Predicate-flow analyses ?
RecursionSummaries tricky with on-the-fly search
Smarter abstractionsHeap data structures ?
34
Predicate AbstractionPredicate Abstraction
P1 : x = y
P3 : x z+1
P2 : z = t + y
P4 : *u = x
Karnaugh Map
:P1,:P2
P1, P2
P1, :P2
:P1, P2
:P3
:P4
:P3
P4
P3
P4
P3
:P4
Set of states
Abstract Set: P1P2P4 Ç : P1 P2 P3 P4
Region Representation: formulas over predicates
35
Predicate AbstractionPredicate Abstraction
Box: abstract variable valuationBoxCover(S): Set of boxes covering STheorem prover used to compute BoxCover
P1 : x = y
P3 : x z+1
P2 : z = t + y
P4 : *u = x
Karnaugh Map
:P1,:P2
P1, P2
P1, :P2
:P1, P2
:P3
:P4
:P3
P4
P3
P4
P3
:P4
36
PostPost##, Pre, Pre
pre(S,op) = { s | 9s’2S. s !op s’} (Weakest Precondition)post(S,op) = { s | 9s’2S. s’ !op s} (Strongest Postcondition)
Abstract Operators: post#
post(S,op) µ post#(S,op)
Concrete Operators: pre Classical Weakest Precondition
:P1,:P2
P1, P2
P1, :P2
:P1, P2
:P3
:P4
:P3
P4
P3
P4
P3
:P4
S
post post(S)post#(S)
53
Model Checking & AbstractionModel Checking & AbstractionProblem: Abstraction too coarse
Solution: Refine abstractionMake boxes smaller