Program Exploration with Pex Nikolai Tillmann, Peli de Halleux Pex

Slides:



Advertisements
Similar presentations
Logical Abstract Interpretation Sumit Gulwani Microsoft Research, Redmond.
Advertisements

Automated Theorem Proving Lecture 1. Program verification is undecidable! Given program P and specification S, does P satisfy S?
Mike Barnett RSDE Microsoft Research Nikolai Tillmann RSDE Microsoft Research TL51.
Leonardo de Moura Microsoft Research. Z3 is a new solver developed at Microsoft Research. Development/Research driven by internal customers. Free for.
Using SMT solvers for program analysis Shaz Qadeer Research in Software Engineering Microsoft Research.
Finding bugs: Analysis Techniques & Tools Symbolic Execution & Constraint Solving CS161 Computer Security Cho, Chia Yuan.
Satisfiability Modulo Theories (An introduction)
SCIP Optimization Suite
Abstraction and Modular Reasoning for the Verification of Software Corina Pasareanu NASA Ames Research Center.
Java Review Interface, Casting, Generics, Iterator.
Parallel Symbolic Execution for Structural Test Generation Matt Staats Corina Pasareanu ISSTA 2010.
Model Counting >= Symbolic Execution Willem Visser Stellenbosch University Joint work with Matt Dwyer (UNL, USA) Jaco Geldenhuys (SU, RSA) Corina Pasareanu.
1 Symbolic Execution for Model Checking and Testing Corina Păsăreanu (Kestrel) Joint work with Sarfraz Khurshid (MIT) and Willem Visser (RIACS)
1/20 Generalized Symbolic Execution for Model Checking and Testing Charngki PSWLAB Generalized Symbolic Execution for Model Checking and Testing.
Ch. 8 Functions.
Symbolic execution © Marcelo d’Amorim 2010.
Leonardo de Moura and Nikolaj Bjørner Microsoft Research.
Leonardo de Moura Microsoft Research. Verification/Analysis tools need some form of Symbolic Reasoning.
Leonardo de Moura Microsoft Research. Satisfiability Modulo Theories: A Calculus of Computation Verification/Analysis tools need some form of Symbolic.
Precise Inter-procedural Analysis Sumit Gulwani George C. Necula using Random Interpretation presented by Kian Win Ong UC Berkeley.
Pexxxx White Box Test Generation for
NP-Complete Problems Reading Material: Chapter 10 Sections 1, 2, 3, and 4 only.
Pex White Box Test Generation for.NET Nikolai Tillmann, Microsoft Research SMT 2008.
Nikolaj Bjørner Leonardo de Moura Nikolai Tillmann Microsoft Research August 11’th 2008.
1 The First Step Learning objectives write Java programs that display text on the screen. distinguish between the eight built-in scalar types of Java;
Software Testing and QA Theory and Practice (Chapter 4: Control Flow Testing) © Naik & Tripathy 1 Software Testing and Quality Assurance Theory and Practice.
272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 4: SMT-based Bounded Model Checking of Concurrent Software.
1 Genericity Parameterizing by Type. 2 Generic Class One that is parameterized by type  Works when feature semantics is common to a set of types On object.
Deep Dive into Pex How Pex works, implications for design of Code Hunt puzzles Nikolai Tillmann Principal Software Engineering Manager Microsoft, Redmond,
Separation of Concerns Tao Xie Peking University, China North Carolina State University, USA In collaboration with Nikolai Tillmann, Peli de Halleux, Wolfram.
Tao Xie (North Carolina State University) Nikolai Tillmann, Jonathan de Halleux, Wolfram Schulte (Microsoft Research, Redmond WA, USA)
CUTE: A Concolic Unit Testing Engine for C Technical Report Koushik SenDarko MarinovGul Agha University of Illinois Urbana-Champaign.
DySy: Dynamic Symbolic Execution for Invariant Inference.
Goals of Course Introduction to the programming language C Learn how to program Learn ‘good’ programming practices.
1 7.Algorithm Efficiency What to measure? Space utilization: amount of memory required  Time efficiency: amount of time required to process the data Depends.
SWE 619 © Paul Ammann Procedural Abstraction and Design by Contract Paul Ammann Information & Software Engineering SWE 619 Software Construction cs.gmu.edu/~pammann/
Leonardo de Moura Microsoft Research. Satisfiability Modulo Theories: An Appetizer Verification/Analysis tools need some form of Symbolic Reasoning.
1 7.Algorithm Efficiency What to measure? Space utilization: amount of memory required  Time efficiency: amount of time required to process the data.
SAT & SMT. Software Verification & Testing SAT & SMT Test case generation Predicate Abstraction Verifying Compilers.
Type Systems CS Definitions Program analysis Discovering facts about programs. Dynamic analysis Program analysis by using program executions.
Tao Xie North Carolina State University Nikolai Tillmann, Peli de Halleux, Wolfram Schulte Microsoft Research.
Code Contracts Parameterized Unit Tests Tao Xie. Example Unit Test Case = ? Outputs Expected Outputs Program + Test inputs Test Oracles 2 void addTest()
Isolated Parameterized Unit Testing with Pex and Moles Nikolai Tillmann, Jonathan “Peli” de Halleux Microsoft Research.
Parameterized Unit Tests By Nikolai Tillmann and Wolfram Schulte Proc. of ESEC/FSE 2005 Presented by Yunho Kim Provable Software Lab, KAIST TexPoint fonts.
Parallelizing MiniSat I-Ting Angelina Lee Justin Zhang May 05, Final Project Presentation.
Leonardo de Moura Microsoft Research. SATTheoriesSMT Arithmetic Bit-vectors Arrays …
Tao Xie (North Carolina State University) Peli de Halleux, Nikolai Tillmann, Wolfram Schulte (Microsoft Research)
Symbolic Execution with Abstract Subsumption Checking Saswat Anand College of Computing, Georgia Institute of Technology Corina Păsăreanu QSS, NASA Ames.
jFuzz – Java based Whitebox Fuzzing
Leonardo de Moura Microsoft Research. Verification/Analysis tools need some form of Symbolic Reasoning.
CSV 889: Concurrent Software Verification Subodh Sharma Indian Institute of Technology Delhi Scalable Symbolic Execution: KLEE.
A System to Generate Test Data and Symbolically Execute Programs Lori A. Clarke Presented by: Xia Cheng.
9 - Class & Method Design Model Enhancement Design to Code Proposal Presentation.
Symbolic and Concolic Execution of Programs Information Security, CS 526 Omar Chowdhury 10/7/2015Information Security, CS 5261.
A Test Case + Mock Class Generator for Coding Against Interfaces Mainul Islam, Christoph Csallner Software Engineering Research Center (SERC) Computer.
Random Interpretation Sumit Gulwani UC-Berkeley. 1 Program Analysis Applications in all aspects of software development, e.g. Program correctness Compiler.
Model Counting with Applications to CodeHunt Willem Visser Stellenbosch University South Africa.
CUTE: A Concolic Unit Testing Engine for C Koushik SenDarko MarinovGul Agha University of Illinois Urbana-Champaign.
( = “unknown yet”) Our novel symbolic execution framework: - extends model checking to programs that have complex inputs with unbounded (very large) data.
Symbolic Execution in Software Engineering By Xusheng Xiao Xi Ge Dayoung Lee Towards Partial fulfillment for Course 707.
Dynamic White-Box Testing What is code coverage? What are the different types of code coverage? How to derive test cases from control flows?
1 7.Algorithm Efficiency These factors vary from one machine/compiler (platform) to another  Count the number of times instructions are executed So, measure.
Satisfiability Modulo Theories and DPLL(T) Andrew Reynolds March 18, 2015.
Control Flow Testing Handouts
A Test Case + Mock Class Generator for Coding Against Interfaces
Code Contracts and Pex Peli de Halleux, Nikolai Tillmann
White-Box Testing Using Pex
Automatic Test Generation SymCrete
CUTE: A Concolic Unit Testing Engine for C
C. M. Overstreet Old Dominion University Fall 2005
Presentation transcript:

Program Exploration with Pex Nikolai Tillmann, Peli de Halleux Pex

Test input generator Pex starts from parameterized unit tests Generated tests are emitted as traditional unit tests Dynamic symbolic execution framework Analysis of.NET instructions (bytecode) Instrumentation happens automatically at JIT time Using SMT-solver Z3 to check satisfiability and generate models = test inputs

class ArrayList { object[] items; int count; ArrayList(int capacity) { if (capacity < 0) throw...; items = new object[capacity]; } void Add(object item) { if (count == items.Length) ResizeArray(); items[this.count++] = item; }... class ArrayListTest { [PexMethod] void AddItem(int c, object item) { var list = new ArrayList(c); list.Add(item); Assert(list[0] == item); } }

class ArrayList { object[] items; int count; ArrayList(int capacity) { if (capacity < 0) throw...; items = new object[capacity]; } void Add(object item) { if (count == items.Length) ResizeArray(); items[this.count++] = item; }... class ArrayListTest { [PexMethod] void AddItem(int c, object item) { var list = new ArrayList(c); list.Add(item); Assert(list[0] == item); } } Inputs

(0,null) class ArrayList { object[] items; int count; ArrayList(int capacity) { if (capacity < 0) throw...; items = new object[capacity]; } void Add(object item) { if (count == items.Length) ResizeArray(); items[this.count++] = item; }... class ArrayListTest { [PexMethod] void AddItem(int c, object item) { var list = new ArrayList(c); list.Add(item); Assert(list[0] == item); } }

InputsObserved Constraints (0,null)!(c<0) class ArrayList { object[] items; int count; ArrayList(int capacity) { if (capacity < 0) throw...; items = new object[capacity]; } void Add(object item) { if (count == items.Length) ResizeArray(); items[this.count++] = item; }... class ArrayListTest { [PexMethod] void AddItem(int c, object item) { var list = new ArrayList(c); list.Add(item); Assert(list[0] == item); } } c < 0  false

InputsObserved Constraints (0,null)!(c<0) && 0==c class ArrayList { object[] items; int count; ArrayList(int capacity) { if (capacity < 0) throw...; items = new object[capacity]; } void Add(object item) { if (count == items.Length) ResizeArray(); items[this.count++] = item; }... class ArrayListTest { [PexMethod] void AddItem(int c, object item) { var list = new ArrayList(c); list.Add(item); Assert(list[0] == item); } } 0 == c  true

InputsObserved Constraints (0,null)!(c<0) && 0==c class ArrayList { object[] items; int count; ArrayList(int capacity) { if (capacity < 0) throw...; items = new object[capacity]; } void Add(object item) { if (count == items.Length) ResizeArray(); items[this.count++] = item; }... class ArrayListTest { [PexMethod] void AddItem(int c, object item) { var list = new ArrayList(c); list.Add(item); Assert(list[0] == item); } } item == item  true This is a tautology, i.e. a constraint that is always true, regardless of the chosen values. We can ignore such constraints.

Constraints to solve InputsObserved Constraints (0,null)!(c<0) && 0==c !(c<0) && 0!=c class ArrayList { object[] items; int count; ArrayList(int capacity) { if (capacity < 0) throw...; items = new object[capacity]; } void Add(object item) { if (count == items.Length) ResizeArray(); items[this.count++] = item; }... class ArrayListTest { [PexMethod] void AddItem(int c, object item) { var list = new ArrayList(c); list.Add(item); Assert(list[0] == item); } }

Constraints to solve InputsObserved Constraints (0,null)!(c<0) && 0==c !(c<0) && 0!=c(1,null) class ArrayList { object[] items; int count; ArrayList(int capacity) { if (capacity < 0) throw...; items = new object[capacity]; } void Add(object item) { if (count == items.Length) ResizeArray(); items[this.count++] = item; }... class ArrayListTest { [PexMethod] void AddItem(int c, object item) { var list = new ArrayList(c); list.Add(item); Assert(list[0] == item); } } Z3 Constraint solver Z3 has decision procedures for - Arrays - Linear integer arithmetic - Bitvector arithmetic - … - (Everything but floating-point numbers)

Constraints to solve InputsObserved Constraints (0,null)!(c<0) && 0==c !(c<0) && 0!=c(1,null)!(c<0) && 0!=c class ArrayList { object[] items; int count; ArrayList(int capacity) { if (capacity < 0) throw...; items = new object[capacity]; } void Add(object item) { if (count == items.Length) ResizeArray(); items[this.count++] = item; }... class ArrayListTest { [PexMethod] void AddItem(int c, object item) { var list = new ArrayList(c); list.Add(item); Assert(list[0] == item); } } 0 == c  false

Constraints to solve InputsObserved Constraints (0,null)!(c<0) && 0==c !(c<0) && 0!=c(1,null)!(c<0) && 0!=c c<0 class ArrayList { object[] items; int count; ArrayList(int capacity) { if (capacity < 0) throw...; items = new object[capacity]; } void Add(object item) { if (count == items.Length) ResizeArray(); items[this.count++] = item; }... class ArrayListTest { [PexMethod] void AddItem(int c, object item) { var list = new ArrayList(c); list.Add(item); Assert(list[0] == item); } }

Constraints to solve InputsObserved Constraints (0,null)!(c<0) && 0==c !(c<0) && 0!=c(1,null)!(c<0) && 0!=c c<0(-1,null) class ArrayList { object[] items; int count; ArrayList(int capacity) { if (capacity < 0) throw...; items = new object[capacity]; } void Add(object item) { if (count == items.Length) ResizeArray(); items[this.count++] = item; }... class ArrayListTest { [PexMethod] void AddItem(int c, object item) { var list = new ArrayList(c); list.Add(item); Assert(list[0] == item); } }

Constraints to solve InputsObserved Constraints (0,null)!(c<0) && 0==c !(c<0) && 0!=c(1,null)!(c<0) && 0!=c c<0(-1,null)c<0 class ArrayList { object[] items; int count; ArrayList(int capacity) { if (capacity < 0) throw...; items = new object[capacity]; } void Add(object item) { if (count == items.Length) ResizeArray(); items[this.count++] = item; }... class ArrayListTest { [PexMethod] void AddItem(int c, object item) { var list = new ArrayList(c); list.Add(item); Assert(list[0] == item); } } c < 0  true

Constraints to solve InputsObserved Constraints (0,null)!(c<0) && 0==c !(c<0) && 0!=c(1,null)!(c<0) && 0!=c c<0(-1,null)c<0 class ArrayList { object[] items; int count; ArrayList(int capacity) { if (capacity < 0) throw...; items = new object[capacity]; } void Add(object item) { if (count == items.Length) ResizeArray(); items[this.count++] = item; }... class ArrayListTest { [PexMethod] void AddItem(int c, object item) { var list = new ArrayList(c); list.Add(item); Assert(list[0] == item); } }

Pex – Test more with less effort Reduce testing costsReduce testing costs Automated analysis, reproducible resultsAutomated analysis, reproducible results Produce more secure softwareProduce more secure software White-box code analysisWhite-box code analysis Produce more reliable softwareProduce more reliable software Analysis based on contracts written as codeAnalysis based on contracts written as code 17

Formulas may be a big conjunction Pre-processing step Eliminate variables and simplify input format Incremental: solve several similar formulas New constraints are asserted. push and pop: (user) backtracking Lemma reuse “Small Models” Given a formula F, find a model M, that minimizes the value of the variables x 0 … x n

How to test this code? (Real code from.NET base class libraries.) 19

20

Test input, generated by Pex 21

Test Inputs Constraint System Execution Path Known Paths Run Test and Monitor Record Path Condition Choose an Uncovered Path Solve Initially, choose Arbitrary

Test Inputs Constraint System Execution Path Known Paths Run Test and Monitor Record Path Condition Choose an Uncovered Path Solve Initially, choose Arbitrary a[0] = 0; a[1] = 0; a[2] = 0; a[3] = 0; … a[0] = 0; a[1] = 0; a[2] = 0; a[3] = 0; …

Test Inputs Constraint System Execution Path Known Paths Run Test and Monitor Record Path Condition Choose an Uncovered Path Solve Initially, choose Arbitrary Path Condition: … ⋀ magicNum != 0x Path Condition: … ⋀ magicNum != 0x

Test Inputs Constraint System Execution Path Known Paths Run Test and Monitor Record Path Condition Choose an Uncovered Path Solve Initially, choose Arbitrary … ⋀ magicNum != 0x … ⋀ magicNum == 0x … ⋀ magicNum != 0x … ⋀ magicNum == 0x

Test Inputs Constraint System Execution Path Known Paths Run Test and Monitor Record Path Condition Choose an Uncovered Path Solve a[0] = 206; a[1] = 202; a[2] = 239; a[3] = 190; a[0] = 206; a[1] = 202; a[2] = 239; a[3] = 190; Initially, choose Arbitrary

Test Inputs Constraint System Execution Path Known Paths Run Test and Monitor Record Path Condition Choose an Uncovered Path Solve Initially, choose Arbitrary

Test Inputs Constraint System Execution Path Known Paths Run Test and Monitor Record Path Condition Choose an Uncovered Path Solve Initially, choose Arbitrary

Independent constraint optimization + Constraint caching (similar to EXE) Idea: Related execution paths give rise to "similar" constraint systems Example: Consider x>y ⋀ z>0 vs. x>y ⋀ z<=0 If we already have a cached solution for a "similar" constraint system, we can reuse it x=1, y=0, z=1 is solution for x>y ⋀ z>0 we can obtain a solution for x>y ⋀ z<=0 by reusing old solution of x>y: x=1, y=0 combining with solution of z<=0: z=0

Decision procedures for uninterpreted functions with equalities, linear integer arithmetic, bitvector arithmetic, arrays, tuples Support for universal quantifiers Used to model custom theories, e.g..NET type system Model generation Models used as test inputs Incremental solving Push / Pop of contexts for model minimization Programmatic API For small constraint systems, text through pipes would add huge overhead

31 ldtokenPoint::GetX call__Monitor::EnterMethod brfalseL0 ldarg.0 call__Monitor::NextArgument<Point> L0:.try {.try { call__Monitor::LDARG_0 ldarg.0 call__Monitor::LDNULL ldnull call__Monitor::CEQ ceq call__Monitor::BRTRUE brtrueL1 call__Monitor::BranchFallthrough call__Monitor::LDARG_0 ldarg.0 … ldtokenPoint::X call__Monitor::LDFLD_REFERENCE ldfldPoint::X call__Monitor::AtDereferenceFallthrough brL2 L1: call__Monitor::AtBranchTarget call__Monitor::LDC_I4_M1 ldc.i4.m1 L2: call__Monitor::RET stloc.0 leaveL4 } catch NullReferenceException { ‘ call__Monitor::AtNullReferenceException rethrow } L4: leaveL5 } finally { call__Monitor::LeaveMethod endfinally } L5:ldloc.0 ret class Point { int x; int y; public static int GetX(Point p) { if (p != null) return p.X; else return -1; } } Prologue Epilogue Calls will perform symbolic computation Calls to build path condition Record concrete values to have all information when this method is called with no proper context (The real C# compiler output is actually more complicated.)