Title: Joining Dataflow with Predicates
1Joining Dataflow with Predicates
- Jeffrey Fischer UC Los Angeles
- Ranjit Jhala UC San Diego
- Rupak Majumdar UC Los Angeles
2Classical dataflow analysis
- Fast and systematic approach to program analysis
- Compute the least fixed-point for a set of
dataflow facts - An eager analysis set of facts is fixed
- Problems
- Imprecision
- Dataflow facts propagated across infeasible
branches - Unification of facts at join points
- Not adaptive may be overwhelmed with irrelevant
facts
Introduction
3Another approach CEGAR
- Start with coarse abstraction and refine based on
infeasible counter examples - Counterexample-guided abstraction and refinement
- Clarke et al, 2000
- Informally called lazy analyses
- Avoids cost of tracking unnecessary information
- gt Scales better to large programs
- Most common approach Predicate abstraction
- Represent program state using first-order
predicates over program variables - Can we use this to regain precision in dataflow
analyses?
Introduction
4Problems with lazy dataflow analysis
- Not always convenient to model program structures
- May require several iterations to find obvious
facts - Limitations in predicate discovery algorithms
Introduction
5Our contributions
- Combine best features of lazy and eager analyses
through predication - Demonstrate effectiveness through symbolic
execution lattice - Implementation in BLAST model checker
Introduction
6Outline
- Motivating example
- Predicated lattices
- Symbolic execution lattice
- Implementation and results
- Related work and conclusion
Introduction
7Example tracking the state of a FILE
FILE out int flag 1 out-gtis_open
1 2 assert(out-gtis_open1) 3 out-gtis_open
0 . . 4 flag 0,1 5 if (flag) 6
out-gtis_open 1 7 else . . 8 if
(flag) 9 assert(out-gtis_open)
FILE out int flag 1 open(out) 2
fprintf(out, ...) 3 close(out) . . 4
flag getIntOpt(dbg) 5 if (flag) 6
open(out) 7 else . . 8 if (flag) 9
fprintf(out, ...)
Simplified program
- Dataflow facts
- out-gtis_open
Motivating example
8An eager dataflow analysis
1 out-gtis_open 1 2 assert(out-gtis_open1)
3 out-gtis_open 0 . .
out-gtis_open ? 1
OK
out-gtis_open ? 0
Motivating example
9An eager dataflow analysis
4 flag 0,1 5 if (flag) 6 out-gtis_open
1 7 else . . 8 if (flag) 9
assert(out-gtis_open)
Error!
Motivating example
10If we track flag, the analysis still fails
4 flag 0,1 5 if (flag) 6 out-gtis_open
1 7 else . . 8 if (flag) 9
assert(out-gtis_open)
Error!
Motivating example
11Predicated Lattices
- For each program location, track a set of
first-order predicates over program variables - Rather than track dataflow facts directly, track
a predicated lattice - Each lattice element maps predicates to original
lattice elements - At join points, only join facts associated with
the same set of predicates - We use true as the default predicate
- Instance of reduced cardinal powers of lattices
Cousot 79
Predicated lattices
12Example
4 flag 0,1 5 if (flag) 6 out-gtis_open
1 7 else . . 8 if (flag) 9
assert(out-gtis_open)
OK
Predicated lattices
13Where do the predicates come from?
- Initially, no predicates are tracked
- Run the dataflow analysis
- Upon finding a counterexample, check whether it
is feasible - If feasible, report an error
- If not feasible, add predicates which rule out
the counterexample - Repeat from step 1
Predicated lattices
14Details of lazy analysis
- Path to error found via search of control flow
graph - Weakest precondition computed backward from error
- If WP to beginning is satisfiable, error is
feasible - If WP not satisfiable, use to find new predicates
- Coverage check used join points to ensure
termination - See Henzinger, et al. 2002 for details
Predicated lattices
15Search for path to error
4 flag 0,1 5 if (flag) 6 out-gtis_open
1 7 else . . 8 if (flag) 9
assert(out-gtis_open)
4 flag 0,1
Error!
Predicated lattices
16Take WP of each statement
4 flag 0,1 5 if (flag) 6 out-gtis_open
1 7 else . . 8 if (flag) 9
assert(out-gtis_open)
Contradiction! WP5 flag0 WP7 WP7 WP8
. . WP8 flag1 out-gtis_open0
WP5 flag0 WP7
Add predicates for flag
WP8 flag1
Predicated lattices
17Rerun with predicates
4 flag 0,1 5 if (flag) 6 out-gtis_open
1 7 else . . 8 if (flag) 9
assert(out-gtis_open)
4 flag 0,1
out-gtis_open ? 0
flag0
out-gtis_open ? 0
flag0
out-gtis_open ? 0
false
Path not feasible!
Predicated lattices
18Symbolic Execution Lattice
- Proof of concept for predicated lattices,
implemented in BLAST model checker - Tracks values of program variables and heap
- Facts at each program point represented as map
from names to values - Symbolic Execution used to compute new facts
after each statement
Symbolic execution lattice
19Symbolic Execution Lattice
- Uncertainty introduced by joins, environment, and
approximations - Use predicated lattice to introduce path
sensitivity as needed - To be sound, must always track potential
points-to relationships
Symbolic execution lattice
20Names
- Program variables
- Fresh name created at each heap allocation call
- To bound the number of names, equivalence classes
defined for heap names - Summary values maintained for multi-valued
equivalence classes
Symbolic execution lattice
21Values
- Constants (integers, strings, etc.)
- Pointers
- Must(addr) definitely points to addr
- May(v,addrSet) may point to any location in
addrSet, with target value v - Special addresses
- null
- Errp
- T (top)
Symbolic execution lattice
22Dataflow fact notation
- Constants name ? constant
- Example x ? 5
- Structures name ? (field1 ? v1, field2 ? v2, )
- Example outp ?(is_open ?1)
- Must-pointers pointer_name ? target name
- Example x ? y
- May-pointers
- ltpointer_namegt ? target1, target2, gt value
- Examples x ? p1, p2 gt 5, y ? T gt 5
Symbolic execution lattice
23Joining dataflow facts
- Dataflow facts are joined
- At join-points in the control flow
- When assigning through a may-pointer
- When computing summary values
Symbolic execution lattice
24Rules for joining values
Symbolic execution lattice
25Example
- int x 0
- int y 1
- int z
- if ()
- z x
-
- else
- z y
-
- ...
- z 5
Symbolic execution lattice
26Another example
- int ex(FILE fp)
- FILE outp
- if ()
- if (fp-gtis_open!1)
- return -1
- else
- outp fp
- else
- outp (FILE)malloc(...)
- fopen(outp, ...)
-
- ...
- assert(outp-gtis_open1)
- ...
OK
Symbolic execution lattice
27Dynamic Allocation
- We partition heap names based on equivalence
classes - All values assigned to equivalence class are
joined together and with T - Different partitioning strategies possible
- Merge all allocations at a given statement
- Merge all allocations at a given statement,
except for most recent - Merge all allocations at a given statement, when
their values agree on some set of 3-valued
predicates - gt Shape Analysis Sagiv,Reps,Wilhelm 99
Symbolic execution lattice
28Implementation in Blast
- Dataflow analyses implemented as lattice plug-ins
to BLAST - Details of each analysis hidden behind an ADT
Implementation and results
29Implementation in BLAST
- Symbolic Execution lattice
- Models arrays as summary nodes
- Full support for structures
- Uses
- Rule out infeasible paths (avoiding
counterexample analysis) - Context sensitive alias analysis
Implementation and results
30Experiments
- Checked MS Windows device drivers
- 14k to 138k lines of preprocessed C code
- Typestate property related to I/O request
protocols - Described by a 22 state automaton
- Compared results with and without symbolic
execution lattice
Implementation and results
31Results
Implementation and results
32Related work
- Tensor analysis
- Cousot,Cousot 79
- Predicated lattices an application of this theory
- We consider implementation issues
- Qualified dataflow analysis
- Holly,Rosen 81, Dwyer,Clarke 96, Dwyer, et
al. 2004 - Key difference our approach automatically
generates qualifications - ESP
- Das,Lerner,Seigle 2002
- ESP provides fixed qualifications based on
property automata - Predicated lattices a generalization of ESP
Related work and conclusion
33Conclusion
- Predicated lattices incrementally add path
- sensitivity to your favorite dataflow analysis
Now you have the advantages of both eager and
lazy analyses.
Related work and conclusion
34Supplemental Slides
35Example an eager dataflow analysis
T
out-gtis_open0, flagT
out-gtis_open1, flagT
out-gtis_openT, flag0
out-gtis_openT, flag1
out-gtis_open0, flag0
out-gtis_open1, flag0
out-gtis_open0, flag1
out-gtis_open1, flag1
T