Title: SLAM Over the Summer
1SLAM Over the Summer
- Wes Weimer
- (Tom Ball, Sriram Rajamani, Manuvir Das)
2SLAM 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
3C program
Spec.
SLIC
GOLF
predicates
Boolean program
CFG VFG
c2bp
bebop
Pass
predicates
newton
Fail, p
GUI
Error
4The 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
5SLAM Termination
- If abstract interpretation with widening
terminates, will SLAM with widening terminate as
well? - Answer Yes.
- Andreas Podelski finished this before I arrived
65 Secrets to Scaling SLAM
- Dont fork() 1 theorem prover per query
- Dont cache theorem prover results
- Do cache theorem prover results (even between
iterations) - Do store the CFG, dont re-parse
- Dont use algorithms that require exponential
stack space
7Specify, 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
8start NP
CallDriver
SKIP2
SKIP1
return child status
Skip
IPC
CallDriver
synch
MPR3
NP
CallDriver
prop completion
PPC
not pending returned
MPR completion
Complete request
CallDriver
MPR1
MPR2
DC
return not Pend
no prop completion
synch
CallDriver
N/A
N/A
IRP accessible
CallDriver
start P
SKIP2
Mark Pending
SKIP1
Skip
IPC
CallDriver
synch
MPR3
NP
CallDriver
return Pending
prop completion
PPC
not pending returned
MPR completion
Complete request
CallDriver
MPR1
MPR2
DC
no prop completion
CallDriver
N?A
9SLAMzilla 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
10Iterative 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
11Value 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
12The 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
13How 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
14Simple Example
- foo(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)
15Value Flow Graph
2
x
z
c
p
a
3
s
v
y
d
q
b
Recall the goal Decide if a b
4
5
16The 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!
17Theory and Practice
Lets try it on the a branch
2
x
z
c
p
a
3
s
v
y
d
q
b
pa cp zc xz 2x 3x
4
5
18The Root of the Problem
Lets try it on the a branch
2
x
z
c
p
a
3
s
v
y
d
q
b
pa // Bad (no scope) cp // OK zc // Bad (no
scope) xz // OK 2x // OK 3x // OK
4
5
19Scoping 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)
20Value Flow Revised
2
x
z
c
p
a
3
s
v
y
d
q
b
Red represents function calls and
returns (crossing scopes)
4
5
21Value Flow Fixup
2
x
z
c
p
a
3
s
v
y
d
q
b
Concentrating just on zc, conceptually add 3c
and 2c, thus adding 3c and 2c
4
5
22Fixup Bonanza
2
x
z
c
p
a
3
s
v
y
d
q
b
4
5
23Why does it work?
There is no scope in which z c is a valid
predicate. However If we know z2 or
z3 We can easily prove c2 or c3 at
the call-site And c2 z2 implies cz
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)
24This 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
25Extensions
- If we know more about the predicate a b, we can
do better - a b, a lt 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
26Variable Equality (ab)
2
x
z
c
p
a
3
s
v
y
d
q
b
Consider the intersection of the ground
terms a3 and b3, etc., should suffice,
right? Sadly, no.
4
5
27Results?
- 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
28SLAM-PCC
- Perhaps not of general interest
- Verify bprogc2bp(preds,cprog)
- requires O(CFG2preds) proofs
- Verify final result
- Standard VCGen(cprog,property)
- Get loop invariants, function pre-post from model
checker
29Questions?