1.53k likes | 1.55k Views
Explore advanced program analysis techniques for optimization, security, and verification. Learn dataflow analysis, slicing concepts, and reachability algorithms. Analyze complex software structures effectively. Tutorial by Thomas Reps, University of Wisconsin.
E N D
ProgramAnalysisvia GraphReachability ThomasReps UniversityofWisconsin http://www.cs.wisc.edu/~reps/ PLDI 00 Tutorial, Vancouver, B.C., June 18, 2000
PLDI 00 Registration Form • PLDI 00: …………………….. $ ____ • Tutorial (morning): …………… $ ____ • Tutorial (afternoon): ………….. $ ____ • Tutorial (evening): ……………. $ – 0 –
Applications • Program optimization • Program-understanding and software-reengineering • Security • information flow • Verification • model checking • security of crypto-based protocols for distributed systems
Slicing & Applications Dataflow Analysis Demand Algorithms CFL Reachability Structure- Transmitted Dependences Set Constraints 1987 1993 1994 1995 1996 1997 1998
. . . As Well As . . . • Flow-insensitive points-to analysis • Complexity results • Linear . . . cubic . . . undecidable variants • PTIME-completeness • Model checking of recursive hierarchical finite-state machines • “infinite”-state systems • linear-time and cubic-time algorithms
. . . And Also • Analysis of attribute grammars • Security of crypto-based protocols for distributed systems [Dolev, Even, & Karp 83] • Formal-language problems • CFL-recognition (given G and , is L(G)?) • 2DPDA- and 2NPDA-simulation • Given M and , is L(M)? • String-matching problems
Unifying Conceptual Modelfor Dataflow-Analysis Literature • Linear-time gen-kill [Hecht 76], [Kou 77] • Path-constrained DFA [Holley & Rosen 81] • Linear-time GMOD [Cooper & Kennedy 88] • Flow-sensitive MOD [Callahan 88] • Linear-time interprocedural gen-kill [Knoop & Steffen 93] • Linear-time bidirectional gen-kill [Dhamdhere 94] • Relationship to interprocedural DFA [Sharir & Pneuli 81], [Knoop & Steffen 92]
Susan Horwitz Mooly Sagiv Genevieve Rosay David Melski David Binkley Michael Benedikt Patrice Godefroid Collaborators
Themes • Harnessing CFL-reachability • Relationship to other analysis paradigms • Exhaustive alg. Demand alg. • Understanding complexity • Linear . . . cubic . . . undecidable • Beyond CFL-reachability
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 Not partial evaluation! void line_count(FILE *f);
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
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
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
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