890 likes | 1.01k Views
EFFICIENT EXPLICIT-STATE MODEL CHECKING FOR PROGRAMS WITH DYNAMICALLY ALLOCATED DATA. Marcelo d’Amorim Ph.D. thesis committee: Gul Agha Jennifer Hou Darko Marinov (advisor, chair) Mahesh Viswanathan August 06, 2007. Testing is important.
E N D
EFFICIENT EXPLICIT-STATE MODEL CHECKING FOR PROGRAMS WITH DYNAMICALLY ALLOCATED DATA Marcelo d’Amorim Ph.D. thesis committee: Gul Agha Jennifer Hou Darko Marinov (advisor, chair) Mahesh Viswanathan August 06, 2007
Testing is important • Programmers develop software with lots of errors • Testing is the dominant approach in industry to assure software quality • But...testing is expensive [NIS02] test automation can assist the programmer in finding errors
model checkers are tools that can assist in the automation of software testing goal: improve model checking for software testing
Reminder about Prelim exam • Work presented at Prelim • Symclat (ASE’06 paper) • Improved software testing without model checking • Mixed Execution (ICFEM’06 paper) • More efficient model checking • Delta Execution Idea • More efficient model checking • Work done since Prelim • Delta Execution (ISSTA’07 paper) focus of my thesis
Model Checking and Testing • Model describes behaviors of a system • description includes states and transition • The model checker performs state-space exploration on the input model • … performs systematic testing model “interesting” behaviors model checker property
Design and implementation models • Traditionally, model checkers operate on design models • FDR [Ros94], SPIN [Hol97], NuSMV [CCGR99], Alloy Analyzer [Jac00]… • Recently, more common for model checkers to operate on programs • JPF [JV01], CMC [MPC+02], Bogor [RDH03], SpecExplorer [VCST05]…
Design and implementation models • Traditionally, model checkers operate on design models • FDR [Ros94], SPIN [Hol97], NuSMV [CCGR99], Alloy Analyzer [Jac00]… • Recently, more common for model checkers to operate on programs • JPF [JV01], CMC [MPC+02], Bogor [RDH03], SpecExplorer [VCST05]… focus
Goal speed up state-space exploration for programs with dynamically allocated data (/OO programs)
Example: test subject • BinarySearchTree (BST) and Node classes: state public class BinarySearchTree { private Node root; private int size; public void add(int info) {…} public boolean remove(int info) {…} } class Node { Node left, right; int info; Node(int info) { this.info = info } } 1 2 2 operations
Example: test sequence • Examples of sequences sequences of method calls from the initial state BinarySearchTree bst = new BinarySearchTree(); bst.add(1); bst.add(2); BinarySearchTree bst = new BinarySearchTree(); bst.add(2); bst.remove(1);
Example scenario: Bounded-Exhaustive Exploration • Examples of sequences explore all sequences up to given bounds: • length of sequence • range of values BinarySearchTree bst = new BinarySearchTree(); bst.add(1); bst.add(2); BinarySearchTree bst = new BinarySearchTree(); bst.add(2); bst.remove(1);
Example scenario: Bounded-Exhaustive Exploration bounds // L: length of sequence // N: number of input values // in most experiments L == N public static void main(int L, int N) { BST bst = new BST(); // empty tree for (int i = 0; i < L; i++) { int methNum = Verify.getInt(0, 1); int value = Verify.getInt(1, N); switch (methNum) { case 0: bst.add(value); break; case 1: bst.remove(value); break; } stopIfVisited(bst); } }
Example: Bounded-Exhaustive Exploration L = N = 2 0 remove(2) add(1) add(2) remove(1) • chooses method and value
Example: Bounded-Exhaustive Exploration L = N = 2 0 remove(2) add(1) add(2) remove(1) 1 1 • chooses method and value • executes transition
Example: Bounded-Exhaustive Exploration L = N = 2 0 remove(2) add(2) add(1) remove(1) 1 1 • chooses method and value • executes transition • explores paths (backtracking)
Example: Bounded-Exhaustive Exploration L = N = 2 0 remove(2) add(2) add(1) remove(1) 2 1 1 1 • chooses method and value • executes transition • explores paths (backtracking)
Example: Bounded-Exhaustive Exploration L = N = 2 0 remove(2) add(2) add(1) remove(1) 0 2 1 1 1 • chooses method and value • executes transition • explores paths (backtracking) • prunes paths (compares state)
Example: Bounded-Exhaustive Exploration L = N = 2 0 remove(2) add(2) add(1) remove(1) 0 0 2 1 1 1 • chooses method and value • executes transition • explores paths (backtracking) • prunes paths (compares state)
Example: Bounded-Exhaustive Exploration L = N = 2 0 remove(2) add(2) add(1) remove(1) 0 0 2 1 1 1 … add(1) • chooses method and value • executes transition • explores paths (backtracking) • prunes paths (compares state) 1 1
Example: Bounded-Exhaustive Exploration L = N = 2 0 remove(2) add(2) add(1) remove(1) 0 0 2 1 1 1 … add(1) • chooses method and value • executes transition • explores paths (backtracking) • prunes paths (compares state) add(2) 1 1 2 1 2
Operations • Costly operations for an important class of model checkers: • execution of transitions • exploration of paths (backtracking) • pruning of paths (state comparison) specific goal is to speed up these operations
Our contributions • Two techniques • Mixed execution • Delta execution (∆Execution) • Overall time reduction • execution (mixed and ∆) • backtracking (∆) • state comparison (∆)
Outline • Introduction & Goal • ∆Execution • Mixed execution (brief) • Related Work and Conclusions
Our Technique: ∆Execution • Observation: • Many of the execution paths in state-space exploration partially overlap • Different states can hold same values ∆Execution exploits these overlaps across executions and states to speed up model checking
Example • Consider separately invoking the method call add(4) on the following two Binary Search Trees BST #1 BST #2 3 3 2 1 1 3 3 2
Example 3 2 1 3 1: public void add(int elem) 2: if (root == null) 3: root = new Node(elem) 4: else 5: for (Node temp = root; true; ) 6: if (temp.info < elem) 7: if (temp.right == null) { 8: temp.right = new Node(elem) 9: break; 10: } else temp = temp.right; 11: } else if (temp.info > elem) { 12: if (temp.left = null) { 13: temp.left = new Node(elem); 14: break; 15: } else temp = temp.left; 16: } else return; // no duplicates 17: size++; 18: }
Example 3 2 1 3 4 2 1 3 4 Execution Trace: 1 , 2 , 4 , 5 , 6 , 7 , 10 5 , 6 , 7 , 8 , 9 , 17 1: public void add(int elem) 2: if (root == null) 3: root = new Node(elem) 4: else 5: for (Node temp = root; true; ) 6: if (temp.info < elem) 7: if (temp.right == null) { 8: temp.right = new Node(elem) 9: break; 10: } else temp = temp.right; 11: } else if (temp.info > elem) { 12: if (temp.left = null) { 13: temp.left = new Node(elem); 14: break; 15: } else temp = temp.left; 16: } else return; // no duplicates 17: size++; 18: }
Example 3 2 1 3 4 2 1 3 4 Execution Trace: 1 , 2 , 4 , 5 , 6 , 7 , 10 5 , 6 , 7 , 8 , 9 , 17 3 1: public void add(int elem) 2: if (root == null) 3: root = new Node(elem) 4: else 5: for (Node temp = root; true; ) 6: if (temp.info < elem) 7: if (temp.right == null) { 8: temp.right = new Node(elem) 9: break; 10: } else temp = temp.right; 11: } else if (temp.info > elem) { 12: if (temp.left = null) { 13: temp.left = new Node(elem); 14: break; 15: } else temp = temp.left; 16: } else return; // no duplicates 17: size++; 18: } 1 3 2 4 1 3 2 4
Example Execution overlap across states 4 4 1 2 overlap across executions 3 1 3 2 4 4 Execution Trace: 1 , 2 , 4 , 5 , 6 , 7 , 10 5 , 6 , 7 , 8 , 9 , 17
∆Execution • Technique: uses “set of states” to perform state-space exploration • Exploits the overlapping on states and executions • Reduce time: • execution of transitions • exploration of paths (backtracking) • pruning of paths (state comparison)
0 1 1 1 1 1 1 2 0 1 2 2 2 2 2 1 1 1 1 2 0 standard exploration 0 0
0 1 1 1 1 1 1 0 2 0 1 2 2 2 2 2 1 1 1 1 2 2 0 0 1 1 1 2 1 1 1 1 2 1 0 2 1 1 0 2 2 2 1 2 1 1 1 2 1 2 2 1 2 0 standard exploration 0 0 delta exploration
Back to our example 3 1 3 2 3 2 1 3 only one execution add(4) only one update on field size 4 4 2 1 1 3 3 2 4 4
∆Execution: Set Operations • Merge: “merges” sets of states into one ∆State • Split: “splits” a set of states into two subsets
Combined Execution & Splitting 3 3 3 3 3 3 3 2 1 1 2 1 1 3 3 2 1 2 2 3 add(4)
Combined Execution & Splitting 3 3 3 3 3 3 3 2 1 1 2 1 1 3 3 2 1 2 2 3 add(4) splits on root.right == null split
Combined Execution & Splitting 3 3 3 3 3 3 3 2 1 1 2 1 1 3 3 2 1 2 2 3 4 4 3 3 2 4 1 4 1 2 add(4) splits on root.right == null split
Combined Execution & Splitting 3 3 3 3 3 3 3 2 1 1 2 1 1 3 3 2 1 2 2 3 4 4 4 4 3 3 2 1 2 4 1 4 1 3 3 1 2 4 2 4 add(4) splits on root.right == null split splits on root.right.right == null split
Combined Execution & Splitting 3 3 3 3 3 3 3 2 1 1 2 1 1 3 3 2 1 2 2 3 4 4 4 4 4 3 3 2 1 1 2 4 1 4 1 3 3 2 1 2 4 2 4 3 4 add(4) splits on root.right == null split splits on root.right.right == null split
Combined Execution & Splitting 3 3 3 3 3 3 3 2 1 1 2 1 1 3 3 2 1 2 2 3 4 4 4 4 4 3 3 2 1 1 2 4 1 4 1 3 3 2 1 2 4 2 4 3 4 add(4) splits on root.right == null split splits on root.right.right == null split reduction in number of executions: standard has 5, delta has 3
Merging 4 4 4 4 4 3 3 2 1 1 2 4 1 4 1 3 3 2 1 2 4 2 4 3 4 4 4 4 4 4 3 3 2 1 1 2 4 1 4 1 3 3 2 1 2 4 2 4 3 4 merges merge
Split + Merging iteration i Si … … … … … iteration i + 1 Si+1 … • Splits during execution • Merges sets of post-states from execution … …
Efficient ∆Execution • Representation of set of concrete states • Program instrumentation • Optimized state comparison
∆Execution: State representation 3 3 3 3 3 3 3 2 1 1 2 1 1 3 3 2 1 2 2 3 • Represents a set of concrete states conceptual representation
Representing state: the State 3 3 3 3 3 ∆Objects 3 3 2 1 1 3 3 3 2 1 1
Representing state: the State 3 3 3 3 3 3 3 2 1 1 2 1 1 3 3 3 2 1 1 ∆Objects for references 2 1 1 ? ?
Representing state: the State 3 3 3 3 3 3 3 2 1 1 2 1 1 3 3 2 3 3 3 2 1 1 2 1 1 ? ? ? ? 3 3 2
Representing state: the State 3 3 3 3 3 3 3 2 1 1 2 1 1 3 3 2 1 2 2 3 3 3 3 2 1 1 2 1 1 ? ? ? ? 3 3 2 ? ? ? ? ? ? ? ? 1 2 2 3
Representing state: the State 3 3 3 3 3 3 3 2 1 1 2 1 1 3 3 2 1 2 2 3 ? ? 3 3 2 ? ? ? ? 3 3 3 2 1 1 2 1 1 ? ? ? ? ? ? 1 2 2 3
Constants 3 3 2 1 1 2 1 1 ? ? ? ? 3 3 2 ? ? ? ? ? ? ? ? becomes constant after split due to root.right == null 3 constants created during merging 1 2 2 3