Download presentation
Presentation is loading. Please wait.
Published byCordelia Parker Modified over 10 years ago
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
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.