Secrets of Software Model Checking Thomas Ball Sriram K. Rajamani Software Productivity Tools...
-
date post
20-Dec-2015 -
Category
Documents
-
view
219 -
download
1
Transcript of Secrets of Software Model Checking Thomas Ball Sriram K. Rajamani Software Productivity Tools...
Secrets of Software Model Checking
Thomas BallSriram K. Rajamani
Software Productivity ToolsMicrosoft Research
http://research.microsoft.com/slam/
Outline
• Overview
• Status and Demo
• Secrets– Leaping loops– Fast predicate abstraction– Predicate generating genie
• Conclusions– more “secrets”
Source Code
TestingDevelopment
PreciseAPI Usage Rules
(SLIC)
Software Model Checking
Read forunderstanding
New API rules
Drive testingtools
Defects
100% pathcoverage
Rules
Static Driver VerifierStatic Driver Verifier
SLAM – Software Model Checking
• Counterexample-driven refinement for C – model = boolean programs– model creation (c2bp)– model checking (bebop)– model refinement (newton)
• SLAM toolkit– build on MSR program analysis infrastructure
SLIC
• Finite state language for stating rules– monitors behavior of C code– temporal safety properties (security automata)– familiar C syntax
• Suitable for expressing control-dominated properties – e.g. proper sequence of events– can encode data values inside state
State Machine for Locking
Unlocked Locked
Error
Rel Acq
Acq
Rel
state {
enum {Locked,Unlocked}
s = Unlocked;
}
KeAcquireSpinLock.entry {
if (s==Locked) abort;
else s = Locked;
}
KeReleaseSpinLock.entry {
if (s==Unlocked) abort;
else s = Unlocked;
}
Locking Rule in SLIC
do {KeAcquireSpinLock();
nPacketsOld = nPackets;
if(request){request = request->Next;KeReleaseSpinLock();nPackets++;
}} while (nPackets != nPacketsOld);
KeReleaseSpinLock();
ExampleDoes this code
obey the locking rule?
do {KeAcquireSpinLock();
if(*){
KeReleaseSpinLock();
}} while (*);
KeReleaseSpinLock();
ExampleModel checking boolean program
(bebop)
U
L
L
L
L
U
L
U
U
U
E
do {KeAcquireSpinLock();
nPacketsOld = nPackets;
if(request){request = request->Next;KeReleaseSpinLock();nPackets++;
}} while (nPackets != nPacketsOld);
KeReleaseSpinLock();
ExampleIs error path feasible
in C program?(newton)
U
L
L
L
U
U
U
E
nPackets = CnPacketsOld = C
nPackets = C+1
C+1 != C
do {KeAcquireSpinLock();
nPacketsOld = nPackets; b := true;
if(request){request = request->Next;KeReleaseSpinLock();nPackets++; b := b? false : *;
}} while (nPackets != nPacketsOld);// !b
KeReleaseSpinLock();
ExampleAdd new predicateto boolean program
(c2bp)
U
L
L
L
L
U
L
U
U
U
E
b : (nPacketsOld == nPackets)
do {KeAcquireSpinLock();
b := true;
if(*){
KeReleaseSpinLock();b := b? false : *;
}} while ( !b );
KeReleaseSpinLock();
b
b
b
b
ExampleModel checking
refined boolean program
(bebop)
b : (nPacketsOld == nPackets)
U
L
L
L
L
U
L
U
U
U
E
b
b
!b
Example
do {KeAcquireSpinLock();
b := true;
if(*){
KeReleaseSpinLock();b := b? false : *;
}} while ( !b );
KeReleaseSpinLock();
b : (nPacketsOld == nPackets)
b
b
b
b
U
L
L
L
L
U
L
U
U
b
b
!b
Model checking refined
boolean program(bebop)
SLAM 2002 Status• March
– Bill Gates review
• May– Windows committed to hire two people with model checking
background to support Static Driver Verifier (SDV)• Byron Cook (Prover, OGI)• Vladimir Levin (Bell Labs, FormalCheck)
• July– running SLAM on 100+ drivers, 20+ properties
• September 3– released SDV-1.00 to Windows
Leaping Loops• Most loops fill/access arrays
– are a pain for counter-example-driven refinement – loop predicates usually are irrelevant
• Example: is foo called twice in a row?if (y==0) foo();for(i = 0; i<100; i++) if (a[i]) y=y+1;if (y==1) foo();
• Many infeasible paths to eliminate due to loop predicate i<100
Goal: eliminate irrelevant loop predicates
if (y==0) foo();
for(i = 0; i<100 ;i++) if (a[i]) y=y+1;
if (y==1) foo();
y==0
entry
foo()
y==1
foo()
i<100
a[i]
y=y+1
Control dependence graph
foo() foo()
y==0
entry
foo()
y==1
foo()
i<100
a[i]
y=y+1
y==0
entry
foo()
y==1
foo()
i<100
a[i]
y=y+1
if (y==0) foo();
for(i = 0; * ;i++) if (a[i]) y=y+1;
if (y==1) foo();
Results
• Without apriori loop abstraction– SLAM sometimes runs out of resources or
time– many refinements of irrelevant loops to find
feasible counterexample
• With abstraction– SLAM always has terminated– few false negatives
c2bp: Predicate Abstraction for C Programs
Given• P : a C program• E = {e1,...,en}, ei pure boolean expression
Produce a boolean program B• same control-flow structure as P• only vars are 3-valued booleans {b1,...,bn}• properties true of B are true of P
Assignment ExampleStatement in P: Predicates in
E:y=y+1; {x==y}Weakest Precondition:wp(y=y+1, x==y) = x==y+1wp(y=y+1, x!=y) = x!=y+1
Strengthenings:S(x==y+1) = false
Boolean abstraction of y=y+1:b = b ? false : *;
S(x!=y+1) = x==y
Strengthening
S(e) is the best predicate over {e1,...,en} that implies e:
• a minterm m is a conjunction d1^...^dn
– di = ei or di = !ei
• S(e) = m, where m e • use decision procedures (theorem
prover) to check implication– O(2n) calls in worst-case
Fast Predicate Abstraction
• Predicate abstraction requires many calls to theorem prover to compute S(e)– for each minterm m over predicates in E
• does m imply e?
• Idea:– compute set of minterms m that imply e
directly via theorem prover data structures
Consider Equalities• Example
– E = { a==b, b==c, c==d, a==c }– S(a==d)
• Many unhelpful minterms– (a==b)^(c==d), etc
• Equality graph induced by E:
a b c da b c da b c d
(a==c)^(c==d)
Efficient Implementation of S(e)
• Graph representation of– equalities– uninterpreted function symbols– inequalities (x < c)
• Computation of good minterms via CFL-reachability query
Example
• E = { p==q, &q==x, **x<5 }
• S(*p<5)
p q==
&q x==
**x 5<
*p<
*p *q==
* *
q *x==
* *
*q **x==
*
The Rest of the Story
• For predicates not in theory (i.e., x<y+c), call theorem prover as before– limit size of minterms for efficiency
• Use Das/Dill refinement to deal with approximation introduced by heuristics– implemented by Satyaki Das, summer 2001
Results
• Before fast predicate abstraction– c2bp was bottleneck in SLAM process
• After fast predicate abstraction– bebop is the bottleneck, as it should be
The Predicate Generating Genie
• Fantasy:– if a genie gave SLAM just the right set of predicates, it
could terminate in one iteration
• Reality:– for a restricted subset of C, find enough predicates so
that SLAM terminates in just one iteration– if program not in restricted subset, find predicates and
then iterate to get remaining predicates
Restricted C Language of Equalities
• v1 = v2
• v = c // c Z
• if (*) stmt1 else stmt2
• v1 = fun(v2, …)
• return v
• abortif(v1 v2) // relop
“Simple” Example
bar(int c, int d) int p,q; p = c; q = d; foo(p,q)
foo(int a, int b) abortif(a b)
main() int x,y,z; x = 2; x = 3; y = 5; y = pick(3); z = x; bar(z,y);
pick(int s) int v; if (*) v = s; else v = 4; return v
Value Flow Graph
2
3
x z
s v
4
5
y
c p a
d q b
bar(int c, int d) int p,q; p = c; q = d; foo(p,q)
foo(int a, int b) abortif(a b)
main() int x,y,z; x = 2; x = 3; y = 5; y = pick(3); z = x; bar(z,y);
pick(int s) int v; if (*) v = s; else v = 4; return v
The Idea
• If we knew the final values of a and b (e.g., “3” and “5”) we could decide a b
• Walk back in the graph from a– for each edge “u v”
• add predicate “u == v”
• Do the same for b
Theory and Practice
2
3
4
5
x z
s v
c
y
p
d
a
q b
p==ac==pz==cx==z 2==x3==x
Let’s try it on the a branch …
Theory and Practice
p==a // bad scopec==pz==c // bad scopex==z 2==x3==x
Let’s try it on the a branch …
2
3
4
5
x z
s v
c
y
p
d
a
q b
Scoping Things Out
There is no scope in which “z == c” is a valid predicate.
But this predicate is necessary!
Solution: link all ground terms to c
bar(int c, int d) int p,q; p = c; q = d; foo(p,q)
main() int x,y,z; x = 2; x = 3; y = 5; y = pick(3); z = x; bar(z,y);
Constraint Propagation
2
3
4
5
x z
s v
c
y
p
d
a
q b
Concentrating just onzc, conceptuallyadd 3c and 2c,thus adding “3==c”and “2==c”
Why does it work?
If we know “z==2” or “z==3”
We can easily prove “c==2” or “c==3” at the call-site
And “c==2 & z==2” implies “c==z”
bar(int c, int d) int p,q; p = c; q = d; foo(p,q)
main() int x,y,z; x = 2; x = 3; y = 5; y = pick(3); z = x; bar(z,y);
Forward Pointer
• Speeding Up Dataflow Analysis Using Flow-Insensitive Pointer AnalysisStephen Adam, Thomas Ball, Manuvir Das, Sorin Lerner,
Sriram K. Rajamani, Mark Seigle, and Westley Weimer
• SAS talk on Thursday morning
Result
Floppy driver (3 iterations instead of 25) 6500 lines, simple spec 21 global predicates 741 local predicates 72 max local in scope
Other Technical “Secrets”
• Program slicing– implementation underway– valuable for getting rid of code that is totally irrelevant
to property under consideration
• Incremental abstraction/model checking– abstraction implemented
• Boolean program minimization– implementation underway
Conclusion:SLAM’s “Secret” to Success
• Specific problem• Safety properties• Shoulders & synergies• Separation of concerns• Summer interns & visitors
– Sagar Chaki, Todd Millstein, Rupak Majumdar (2000)– Satyaki Das, Wes Weimer, Robby (2001)– Jakob Lichtenberg, Mayur Naik (2002)– Giorgio Delzanno, Andreas Podelski, Stefan Schwoon