Presentation is loading. Please wait.

Presentation is loading. Please wait.

Thin Slicing Manu Sridharan, Stephen J. Fink, Rastislav Bodík.

Similar presentations


Presentation on theme: "Thin Slicing Manu Sridharan, Stephen J. Fink, Rastislav Bodík."— Presentation transcript:

1 Thin Slicing Manu Sridharan, Stephen J. Fink, Rastislav Bodík

2 What is slicing good for?  Identifies statements in code that affect a particular seed statement  Debugging  Code understanding  This paper  Argues traditional slicing captures too many statements in most cases  Focuses on static slicing for Java (but could be applied to other languages as well)

3 Overview  Definition & motivation  Thin slice expansion  Computing slices  Context-sensitive algorithm  Context-insensitive algorithm  Evaluation

4 Traditional slicing  Traditional definition  “executable program subset in which the seed statement performs the same computation as in the original program”  Too much information to be helpful  In worst case, may include entire program!  May have irrelevant information  Statements that have no direct effect on the seed statement

5 Thin slicing looks for producer statements – statements that directly compute values for the seed statement class Vector { Object[] elems; int count; Vector() {elems = new Object[10];} void add(Object p) { this.elems[count++] = p; } Object get(int ind) { return this.elems[ind]; }... } Vector readNames(InputStream input) { Vector firstNames = new Vector(); while (!eof(input)) { String fullName = readFullName(input); int space = fullName.indexOf(’ ’); String firstName = fullName.substring(0,space-1); firstNames.add(firstName); } return firstNames; } void printNames(Vector firstNames) { for (int i = 0; i < firstNames.size(); i++) { String firstName = (String) firstNames.get(i); print(“FIRSTNAME:“ + firstName); } void main(String[] args) { Vector firstNames = readNames(new InputStream(args[0])); SessionState s = getState(); s.setNames(firstNames);...; SessionState t = getState(); printNames(t.getNames()); }

6 Thin slicing: definition  direct use  Statement s directly uses a location L iff s uses L for some computation other than a pointer derefrence  e.g. y = x.f  producer  Statement t is a producer for a seed s iff 1) s = t or 2) t writes to a location directly used by some other producer  Thin slicing: A subset of the traditional slice containing ONLY producer statements

7 ENTER printNames ENTER main call printNames call readNames s.setNames(firstNames) SessionState s = getState() print(“FIRSTNAME:” + firstName); ENTER readNames input = input_infirstNames_out = firstNames String firstName = fullName.substring(0, space-1) firstNames_in =t.getNames() firstNames = firstNames_in firstNames = firstNames_out SessionState t = getState() String fullName = readFullName(input) call get call add while(!eof(input)) ENTER add this.elems[count++] = p p_in = firstName args = args_in ENTER get ind = ind_in get_out = this.elems[ind] firstName = firstNames.get_out ind_in = i input_in = new InputStream(args[0])) for (int i = 0; i < firstNames.size(); i++) this_in this_out p = p_in int space = fullName.indexOf(‘ ‘)

8 ENTER printNames ENTER main call printNames call readNames s.setNames(firstNames) SessionState s = getState() print(“FIRSTNAME:” + firstName); ENTER readNames input = input_infirstNames_out = firstNames String firstName = fullName.substring(0, space-1) firstNames_in =t.getNames() firstNames = firstNames_in firstNames = firstNames_out SessionState t = getState() String fullName = readFullName(input) call get call add while(!eof(input)) ENTER add this.elems[count++] = p p_in = firstName args = args_in ind = ind_in get_out = this.elems[ind] firstName = firstNames.get_out ind_in = i input_in = new InputStream(args[0])) for (int i = 0; i < firstNames.size(); i++) p = p_in int space = fullName.indexOf(‘ ‘) ENTER get

9 Categorizing statements  Categorize statements in traditional slice  Producer statements  Explainer statements  Heap-based value flow – value flow may occur through aliasing pointers in the heap  Control flow – show conditions under which producer statements execute 1x = new A(); 2z = x; 3y = new B(); 4w = x; 5w.f = y; 6if (w == z) { 7 v = z.f; 8} Producer Heap-based value flow Seed Control flow

10 Expanding thin slices  Thin slices may be too thin  May not contain enough information  Idea: Hierarchically expand the slices to include explainer statements  In the limit → compute a traditional slice

11 Expanding to include control flow  A problem statement may only be executed under some condition  Observation: When considering control flow, in most cases, looking at the control statements lexically close to the statement in question is enough 1readFromFile(File f) { 2 boolean open = f.isOpen(); 3 if (!open) 4 throw new ClosedException(); 5 } 6 … 7}

12 Producer (1) Producer (2) Seed #1 Seed #2 Expanding to explain heap-value flow 1Class File { 2 boolean open; 3 File() { …; this.open = true; } 4 isOpen() { return this.open; } 5 close() { …; this.open = false; } 6 … 7} 8readFromFile(File f) { 9 boolean open = f.isOpen(); 10 if (!open) 11 throw new ClosedException(); 12 } … 13} 14main() { 15 File f = new File(); 16 Vector files = new Vector(); 17 files.add(f); 18 …; 19 File g = (File)files.get(i); 20 g.close(); 21 …; 22 File h = (File)files.get(i); 23 readFromFile(h); 24}

13 Computing thin slices  Use SSA form for analysis (flow sensitivity)  Create a subset of the system dependence graph (SDG)  Requires precise points-to analysis  Call graph for interprocedural dependencies  Heap-based data flow  Basic SDG construction  For x=e, add edges to all statements using x excluding pointer dereferences (x.f)  For method calls, query call graph to find possible targets; add an edge from the actual parameter node to the corresponding formal parameter node

14 Context insensitive  Handles heap accesses by:  For a statement x.f := e, add an edge to each statement with an expression w.f on it’s right hand side, such that the pre- computed points-to analysis indicates x may alias w.  Transitive closure gives the thin slice

15 Context insensitive SDG construction 1 Class Entry { 2 int a, b; 3 } 4 int addEntry(Entry x) { 5 int y = x.a + x.b; 6 return y; 7 } 8 main() { 9 Entry f = new Entry(); 10 f.a = 1; 11 f.b = 3; 12 13 List z = new List(z); 14 z.addEntry(f); 15 Entry g = z.getEntry(); 16 int j = g.a; 17 int i = addEntry(g); 18 } y = x.a + x.b f.a = 1 f.b = 3 int j = g.a

16 Context sensitive  Handles heap accesses by:  For a statement x.f := e, add an edge to each statement with expression w.f on its right-hand side in the same procedure such that the pre-computed points-to analysis indicates x may alias w.  Compute reachability (as in traditional slicing) to construct thin slice  Generally – can be expensive for large programs  Does not provide much improvement over context- insensitive

17 Context sensitive SDG construction 1 Class Entry { 2 int a, b; 3 } 4 int addEntry(Entry x) { 5 int y = x.a + x.b; 6 return y; 7 } 8 main() { 9 Entry f = new Entry(); 10 f.a = 1; 11 f.b = 3; 12 13 List z = new List(z); 14 z.addEntry(f); 15 Entry g = z.getEntry(); 16 int j = g.a; 17 int i = addEntry(g); 18 } y = x.a + x.b f.a = 1 f.b = 3 int j = g.a

18 Evaluation  Context insensitive thin slice computation time insignificant with respect to computing points-to and call graph information  6 seconds vs. 5 minutes  Context sensitive often exhausts memory for larger programs  Points-to analysis precision is KEY  On average – requires 3.3X fewer statements to identify a bug than traditional slicing


Download ppt "Thin Slicing Manu Sridharan, Stephen J. Fink, Rastislav Bodík."

Similar presentations


Ads by Google