910 likes | 1.06k Vues
This document discusses program analysis through graph reachability methods and slicing techniques, presented by Thomas Reps from the University of Wisconsin. The paper reviews various applications such as program optimization, understanding software engineering, and detecting static bugs. In-depth algorithms such as CFL-reachability, demand algorithms, and backward slicing are illustrated with code examples. The significance of slices for program understanding, restructuring, specialization, and testing is highlighted, demonstrating the value of these methodologies in software development.
E N D
ProgramAnalysisvia GraphReachability ThomasReps UniversityofWisconsin http://www.cs.wisc.edu/~reps/ Seehttp://www.cs.wisc.edu/wpis/papers/tr1386.ps
PLDI 00 Registration Form • PLDI 00: …………………….. $ ____ • Tutorial (morning): …………… $ ____ • Tutorial (afternoon): ………….. $ ____ • Tutorial (evening): ……………. $ – 0 –
Slicing & Applications Dataflow Analysis Demand Algorithms CFL Reachability Structure- Transmitted Dependences Set Constraints 1987 1993 1994 1995 1996 1997 1998
Applications • Program optimization • Software engineering • Program understanding • Reengineering • Static bug-finding • Security (information flow)
Susan Horwitz Mooly Sagiv Genevieve Rosay David Melski David Binkley Michael Benedikt Patrice Godefroid Collaborators
Themes • Harnessing CFL-reachability • Exhaustive alg. Demand alg.
Backward slicewith respect to “printf(“%d\n”,i)” Backward Slice int main() { int sum = 0; int i = 1; while (i < 11) { sum = sum + i; i = i + 1; } printf(“%d\n”,sum); printf(“%d\n”,i); }
Backward Slice int main() { int sum = 0; int i = 1; while (i < 11) { sum = sum + i; i = i + 1; } printf(“%d\n”,sum); printf(“%d\n”,i); } Backward slicewith respect to “printf(“%d\n”,i)”
Slice Extraction int main() { int i = 1; while (i < 11) { i = i + 1; } printf(“%d\n”,i); } Backward slicewith respect to “printf(“%d\n”,i)”
Forward slicewith respect to “sum = 0” Forward Slice int main() { int sum = 0; int i = 1; while (i < 11) { sum = sum + i; i = i + 1; } printf(“%d\n”,sum); printf(“%d\n”,i); }
Forward Slice int main() { intsum = 0; int i = 1; while (i < 11) { sum = sum + i; i = i + 1; } printf(“%d\n”,sum); printf(“%d\n”,i); } Forward slicewith respect to “sum = 0”
What Are Slices Useful For? • Understanding Programs • What is affected by what? • Restructuring Programs • Isolation of separate “computational threads” • Program Specialization and Reuse • Slices = specialized programs • Only reuse needed slices • Program Differencing • Compare slices to identify changes • Testing • What new test cases would improve coverage? • What regression tests must be rerun after a change?
Line-Character-Count Program void line_char_count(FILE *f) { int lines = 0; int chars; BOOL eof_flag = FALSE; int n; extern void scan_line(FILE *f, BOOL *bptr, int *iptr); scan_line(f, &eof_flag, &n); chars = n; while(eof_flag == FALSE){ lines = lines + 1; scan_line(f, &eof_flag, &n); chars = chars + n; } printf(“lines = %d\n”, lines); printf(“chars = %d\n”, chars); }
Character-Count Program void char_count(FILE *f) { int lines = 0; int chars; BOOL eof_flag = FALSE; int n; extern void scan_line(FILE *f, BOOL *bptr, int *iptr); scan_line(f, &eof_flag, &n); chars = n; while(eof_flag == FALSE){ lines = lines + 1; scan_line(f, &eof_flag, &n); chars = chars + n; } printf(“lines = %d\n”, lines); printf(“chars = %d\n”, chars); }
Line-Character-Count Program void line_char_count(FILE *f) { int lines = 0; int chars; BOOL eof_flag = FALSE; int n; extern void scan_line(FILE *f, BOOL *bptr, int *iptr); scan_line(f, &eof_flag, &n); chars = n; while(eof_flag == FALSE){ lines = lines + 1; scan_line(f, &eof_flag, &n); chars = chars + n; } printf(“lines = %d\n”, lines); printf(“chars = %d\n”, chars); }
Line-Count Program void line_count(FILE *f) { int lines = 0; int chars; BOOL eof_flag = FALSE; int n; extern void scan_line2(FILE *f, BOOL *bptr, int *iptr); scan_line2(f, &eof_flag, &n); chars = n; while(eof_flag == FALSE){ lines = lines + 1; scan_line2(f, &eof_flag, &n); chars = chars + n; } printf(“lines = %d\n”, lines); printf(“chars = %d\n”, chars); }
wc -c wc -l Specialization Via Slicing wc -lc
Control Flow Graph int main() { int sum = 0; int i = 1; while (i < 11) { sum = sum + i; i = i + 1; } printf(“%d\n”,sum); printf(“%d\n”,i); } Enter F sum = 0 i = 1 printf(sum) printf(i) while(i < 11) T sum = sum + i i = i + i
Control Dependence Graph int main() { int sum = 0; int i = 1; while (i < 11) { sum = sum + i; i = i + 1; } printf(“%d\n”,sum); printf(“%d\n”,i); } Control dependence q is reached from p if condition p is true (T), not otherwise. p q T Similar for false (F). p q F Enter T T T T T T sum = 0 i = 1 printf(sum) printf(i) while(i < 11) T T sum = sum + i i = i + i
Flow Dependence Graph int main() { int sum = 0; int i = 1; while (i < 11) { sum = sum + i; i = i + 1; } printf(“%d\n”,sum); printf(“%d\n”,i); } Flow dependence Value of variable assigned at p may be used at q. p q Enter i = 1 sum = 0 printf(sum) printf(i) while(i < 11) sum = sum + i i = i + i
Program Dependence Graph (PDG) int main() { int sum = 0; int i = 1; while (i < 11) { sum = sum + i; i = i + 1; } printf(“%d\n”,sum); printf(“%d\n”,i); } Control dependence Flow dependence Enter T T T T T T sum = 0 i = 1 printf(sum) printf(i) while(i < 11) T T sum = sum + i i = i + i
Opposite Order Same PDG Program Dependence Graph (PDG) int main() { int i = 1; int sum = 0; while (i < 11) { sum = sum + i; i = i + 1; } printf(“%d\n”,sum); printf(“%d\n”,i); } Enter T T T T T T sum = 0 i = 1 printf(sum) printf(i) while(i < 11) T T sum = sum + i i = i + i
Backward Slice int main() { int sum = 0; int i = 1; while (i < 11) { sum = sum + i; i = i + 1; } printf(“%d\n”,sum); printf(“%d\n”,i); } Enter T T T T T T sum = 0 i = 1 printf(sum) printf(i) while(i < 11) T T sum = sum + i i = i + i
Backward Slice (2) intmain() { int sum = 0; int i = 1; while (i < 11) { sum = sum + i; i = i + 1; } printf(“%d\n”,sum); printf(“%d\n”,i); } Enter T T T T T T sum = 0 i = 1 printf(sum) printf(i) while(i < 11) T T sum = sum + i i = i + i
Backward Slice (3) intmain() { int sum = 0; int i = 1; while (i < 11) { sum = sum + i; i = i + 1; } printf(“%d\n”,sum); printf(“%d\n”,i); } Enter T T T T T T sum = 0 i = 1 printf(sum) printf(i) while(i < 11) T T sum = sum + i i = i + i
Backward Slice (4) intmain() { int sum = 0; int i = 1; while (i < 11) { sum = sum + i; i = i + 1; } printf(“%d\n”,sum); printf(“%d\n”,i); } Enter T T T T T T sum = 0 i = 1 printf(sum) printf(i) while(i < 11) T T sum = sum + i i = i + i
Slice Extraction intmain() { int i = 1; while (i < 11) { i = i + 1; } printf(“%d\n”,i); } Enter T T T T i = 1 printf(i) while(i < 11) T i = i + i
You get a new page Or you move to an internal tag Browsing a Dependence Graph Pretend this is your favorite browser What does clicking on a link do?
Backward slicewith respect to “printf(“%d\n”,i)” Interprocedural Slice int main() { int sum = 0; int i = 1; while (i < 11) { sum = add(sum,i); i = add(i,1); } printf(“%d\n”,sum); printf(“%d\n”,i); } int add(int x, int y) { return x + y; }
Interprocedural Slice int main() { int sum = 0; int i = 1; while (i < 11) { sum = add(sum,i); i = add(i,1); } printf(“%d\n”,sum); printf(“%d\n”,i); } int add(int x, int y) { return x + y; } Backward slicewith respect to “printf(“%d\n”,i)”
Interprocedural Slice int main() { int sum = 0; int i = 1; while (i < 11) { sum = add(sum,i); i = add(i,1); } printf(“%d\n”,sum); printf(“%d\n”,i); } int add(int x, int y) { return x + y; } Superfluous components included by Weiser’s slicing algorithm [TSE 84] Left out by algorithm of Horwitz, Reps, & Binkley [PLDI 88; TOPLAS 90]
System Dependence Graph (SDG) Enter main Call p Call p Enterp
SDG for the Sum Program Enter main while(i < 11) sum = 0 i = 1 printf(sum) printf(i) Call add Call add yin = i xin = sum sum = xout xin = i yin= 1 i = xout Enter add x = xin y = yin x = x + y xout = x
Interprocedural Backward Slice Enter main Call p Call p Enter p
InterproceduralBackward Slice (2) Enter main Call p Call p Enter p
Interprocedural Backward Slice (3) Enter main Call p Call p Enter p
Interprocedural Backward Slice (4) Enter main Call p Call p Enter p
Interprocedural Backward Slice (5) Enter main Call p Call p Enter p
[ ) ( ] Interprocedural Backward Slice (6) Enter main Call p Call p Enter p
( ) [ ) Matched-Parenthesis Path
Interprocedural Backward Slice (6) Enter main Call p Call p Enter p
Interprocedural Backward Slice (7) Enter main Call p Call p Enter p
Slice Extraction Enter main Call p Enter p
Slice of the Sum Program Enter main while(i < 11) i = 1 printf(i) Call add xin = i yin= 1 i = xout Enter add x = xin y = yin x = x + y xout = x
CFL-Reachability[Yannakakis 90] • G: Graph (N nodes, E edges) • L: A context-free language • L-path from s to t iff • Running time: O(N 3)
Interprocedural Slicingvia CFL-Reachability • Graph: System dependence graph • L: L(matched) [roughly] • Node m is in the slice w.r.t. n iff there is an L(matched)-path from m to n