slam over the summer
DESCRIPTION
SLAM Over the Summer. Wes Weimer (Tom Ball, Sriram Rajamani, Manuvir Das). SLAM in 60 seconds. Question: does program meet safety policy? If not, give a counter-example 1. Instrument C program with policy 2. Abstract C program to boolean program 3. Model-check boolean program - PowerPoint PPT PresentationTRANSCRIPT
SLAM Over the Summer
Wes Weimer(Tom Ball, Sriram Rajamani,
Manuvir Das)
SLAM in 60 seconds
• Question: does program meet safety policy?– If not, give a counter-example
• 1. Instrument C program with policy• 2. Abstract C program to boolean program• 3. Model-check boolean program• 4. Is resulting error trace feasible? • 5. If not, refine abstraction, goto 2
C program
Boolean programc2bp
bebop
Fail, p
Pass
newton
GOLF
SLIC
CFG + VFG
predicates
Error GUI
Spec.
predicates
The Cunning Plan
• Study SLAM termination• Make SLAM scale to real programs• Come up with interesting specifications• Run SLAM on device drivers• Find bugs• Retire to a life of luxury, resting on laurels
SLAM Termination
• If abstract interpretation with widening terminates, will SLAM with widening terminate as well?
• Answer: Yes.
• Andreas Podelski finished this before I arrived …
5 Secrets to Scaling SLAM
• Don’t fork() 1 theorem prover per query• Don’t cache theorem prover results• Do cache theorem prover results (even
between iterations)• Do store the CFG, don’t re-parse• Don’t use algorithms that require
exponential stack space
Specify, specify, specify
• SLAM specifications (“slic”)– are like monitors – instrument function calls, returns– can mimic a sort of type state
• A week or two after I arrived, Manuel Fandrich wrote up a lovely IO spec
MPR3
CallDriverMPR
completion
synch
not pending returned
SKIP2
IPCCallDriverSkip return
child status
DC
Completerequest
returnnot Pend
PPCprop
completionCallDriver
N/A
no propcompletion
CallDriver
start NP
returnPending
NP
MPR1
MPRcompletion
SKIP2
IPCCallDriver
CallDriver
DC
Completerequest
PPCprop
completionCallDriver
N?A
no propcompletion
CallDriver
start P Mark Pending
IRP accessible N/A
synch
SKIP1CallDriver
SKIP1Skip
MPR2 MPR1
NP
MPR3
CallDrivernot pending returned
MPR2
synch
SLAMzilla vs. moNThra
• “Classic” SLAM does not scale– 25 iterations on floppy.c (for a simpler spec)– each iter adds a few predicates, repeats work– see “Lazy Abstraction” / BLAST project
• “Classic” SLAM vs. NT: either SLAM– has an internal error– fails to terminate– exhausts virtual memory
Iterative Predicate Generation
• Normally SLAM starts with all predicates mentioned in the spec
• Must rediscover “unintersting” predicates• Example:• x = y;• if (x == FAILURE) abort();
• One iteration just to get “y == FAILURE”
Value Flow Idea
• Run some Value Flow algorithm on instrumented program
• See what values can flow into final important “if” statements
• Generate those predicates in advance• Rejoice as SLAM actually terminates
The Magic Bullet Theory
• For a restricted subset of C• Find enough predicates• So that SLAM terminates correctly• In just 1 iteration
• If real program not in restricted subset of C, iterate to find remaining predicates
How restricted?
• v1 = v2
• v = i // (i Z)• if (*) stmt1 else stmt2
• v1 = fun(v2, …)• return v• abortif(v1 v2) // some relop
• sometimes v1 = v2 v3 // some binops
“Simple” Examplefoo(int a, int b) abortif(a b)
pick(int s) int v; if (*) v = s; else v = 4; return v
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);
Value Flow Graph
2
3
4
5
x z
s v
c
y
p
d
a
q b
Recall the goal:Decide if a b
The Lofty Ideal
• 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• Take every edge “x z”, “2 x”• Add the predicates “x == z”, “2 == x”• Do the same for b• Voila!
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 …
The Root of the Problem
2
3
4
5
x z
s v
c
y
p
d
a
q b
p==a // Bad (no scope)c==p // OKz==c // Bad (no scope)x==z // OK2==x // OK3==x // OK
Let’s try it on the a branch …
Scoping Things OutThere 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);
Value Flow Revised
2
3
4
5
x z
s v
c
y
p
d
a
q b
Red representsfunction calls and returns(crossing scopes)
Value Flow Fixup
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”
Fixup Bonanza
2
3
4
5
x z
s v
c
y
p
d
a
q b
Why does it work?There is no scope in which
“z == c” is a valid predicate. However…
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);
This is Weak
• It relies on having a constant, finite set of “ground terms” (like “2” and “3”)
• It will generate many more predicates than necessary (it ignores control-flow)
• a b only works if the result is a ground term that reaches a or b (e.g., no *p)
• But we have iteration to pick up the pieces
Extensions
• If we know more about the predicate a b, we can do better:
• a b, a < b, etc.– Run algorithm as before, generate “x 5” instead
of “x == 5”, keep “vi == vj”
• a = 5– Run algorithm as before, ignore actual set of
ground terms, always generate “vi == 5”
Variable Equality (a==b)
2
3
4
5
x z
s v
c
y
p
d
a
q b
Consider the intersectionof the ground terms:“a==3” and “b==3”, etc.,should suffice, right?Sadly, no.
Results? Floppy driver (1 bug) (3 iterations instead of 25)
6500 lines, simple spec 21 global predicates 741 local predicates 72 max local in scope
Battery driver (2 bugs) (8 iterations instead of crashing) 2410 lines, that complex spec 18 global predicates 137 local predicates 24 max local in scope
SLAM-PCC
• Perhaps not of general interest• Verify bprog=c2bp(preds,cprog)
– requires O(|CFG|*2|preds|) proofs• Verify final result:
– Standard VCGen(cprog,property)– Get loop invariants, function pre-post from
model checker
Questions?