Amal Khalil & Juergen Dingel

Slides:



Advertisements
Similar presentations
iRobot: An Intelligent Crawler for Web Forums
Advertisements

1 Verification by Model Checking. 2 Part 1 : Motivation.
A Polynomial-Time Algorithm for Global Value Numbering SAS 2004 Sumit Gulwani George C. Necula.
Program Verification using Probabilistic Techniques Sumit Gulwani Microsoft Research Invited Talk: VSTTE Workshop August 2006 Joint work with George Necula.
2. Getting Started Heejin Park College of Information and Communications Hanyang University.
Precise Interprocedural Analysis using Random Interpretation Sumit Gulwani George Necula UC-Berkeley.
Program Analysis using Random Interpretation Sumit Gulwani UC-Berkeley March 2005.
Constraint Satisfaction Problems
Analysis of Computer Algorithms
Cognitive Radio Communications and Networks: Principles and Practice By A. M. Wyglinski, M. Nekovee, Y. T. Hou (Elsevier, December 2009) 1 Chapter 12 Cross-Layer.
Exploring Traversal Strategy for Web Forum Crawling Yida Wang, Jiang-Ming Yang, Wei Lai, Rui Cai, Lei Zhang and Wei-Ying Ma Chinese Academy of Sciences.
1 Automating the Generation of Mutation Tests Mike Papadakis and Nicos Malevris Department of Informatics Athens University of Economics and Business.
All You Ever Wanted to Know About Dynamic Taint Analysis & Forward Symbolic Execution (but might have been afraid to ask) Edward J. Schwartz, ThanassisAvgerinos,
Cristian Cadar, Peter Boonstoppel, Dawson Engler RWset: Attacking Path Explosion in Constraint-Based Test Generation TACAS 2008, Budapest, Hungary ETAPS.
Chapter 4: Informed Heuristic Search
Chapter 14 Software Testing Techniques - Testing fundamentals - White-box testing - Black-box testing - Object-oriented testing methods (Source: Pressman,
1 Verification of Parameterized Systems Reducing Model Checking of the Few to the One. E. Allen Emerson, Richard J. Trefler and Thomas Wahl Junaid Surve.
1 Column Generation. 2 Outline trim loss problem different formulations column generation the trim loss problem master problem and subproblem in column.
Randomized Algorithms Randomized Algorithms CS648 1.
1 Software Unit Test Coverage And Test Adequacy Hong Zhu, Patrick A. V. Hall, John H.R. May Presented By: Arpita Gandhi.
Kai Pan, Xintao Wu University of North Carolina at Charlotte Database State Generation via Dynamic Symbolic Execution for Coverage Criteria Tao Xie North.
Routing and Congestion Problems in General Networks Presented by Jun Zou CAS 744.
Lecture plan Outline of DB design process Entity-relationship model
Lecture 8: Testing, Verification and Validation
Formal models of design 1/28 Radford, A D and Gero J S (1988). Design by Optimization in Architecture, Building, and Construction, Van Nostrand Reinhold,
Chapter 5 Loops Liang, Introduction to Java Programming, Tenth Edition, (c) 2015 Pearson Education, Inc. All rights reserved.
CS 240 Computer Programming 1
25 seconds left…...
Systems Analysis and Design in a Changing World, Fifth Edition
Local Search Jim Little UBC CS 322 – CSP October 3, 2014 Textbook §4.8
CPSC 322, Lecture 14Slide 1 Local Search Computer Science cpsc322, Lecture 14 (Textbook Chpt 4.8) Oct, 5, 2012.
Copyright © 2009 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Java Software Solutions Foundations of Program Design Sixth Edition by Lewis.
1 Decidability continued…. 2 Theorem: For a recursively enumerable language it is undecidable to determine whether is finite Proof: We will reduce the.
Reliable and Efficient Programming Abstractions for Sensor Networks Nupur Kothari, Ramki Gummadi (USC), Todd Millstein (UCLA) and Ramesh Govindan (USC)
New Opportunities for Load Balancing in Network-Wide Intrusion Detection Systems Victor Heorhiadi, Michael K. Reiter, Vyas Sekar UNC Chapel Hill UNC Chapel.
L6:CSC © Dr. Basheer M. Nasef Lecture #6 By Dr. Basheer M. Nasef.
Liang, Introduction to Java Programming, Eighth Edition, (c) 2011 Pearson Education, Inc. All rights reserved Chapter 3 Loops.
A Survey of Approaches for Automated Unit Testing
Masahiro Fujita Yoshihisa Kojima University of Tokyo May 2, 2008
Symbolic Execution with Mixed Concrete-Symbolic Solving
PLDI’2005Page 1June 2005 Example (C code) int double(int x) { return 2 * x; } void test_me(int x, int y) { int z = double(x); if (z==y) { if (y == x+10)
Abstraction and Modular Reasoning for the Verification of Software Corina Pasareanu NASA Ames Research Center.
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.
Hybrid Concolic Testing Rupak Majumdar Koushik Sen UC Los Angeles UC Berkeley.
CSE503: SOFTWARE ENGINEERING SYMBOLIC TESTING, AUTOMATED TEST GENERATION … AND MORE! David Notkin Spring 2011.
ECE Synthesis & Verification1 ECE 667 Spring 2011 Synthesis and Verification of Digital Systems Verification Introduction.
DART Directed Automated Random Testing Patrice Godefroid, Nils Klarlund, and Koushik Sen Syed Nabeel.
DART: Directed Automated Random Testing Koushik Sen University of Illinois Urbana-Champaign Joint work with Patrice Godefroid and Nils Klarlund.
Symbolic Execution with Mixed Concrete-Symbolic Solving (SymCrete Execution) Jonathan Manos.
CUTE: A Concolic Unit Testing Engine for C Technical Report Koushik SenDarko MarinovGul Agha University of Illinois Urbana-Champaign.
CSV 889: Concurrent Software Verification Subodh Sharma Indian Institute of Technology Delhi Symbolic Execution.
Symbolic Execution with Abstract Subsumption Checking Saswat Anand College of Computing, Georgia Institute of Technology Corina Păsăreanu QSS, NASA Ames.
Xusheng Xiao North Carolina State University CSC 720 Project Presentation 1.
Learning Symbolic Interfaces of Software Components Zvonimir Rakamarić.
CSV 889: Concurrent Software Verification Subodh Sharma Indian Institute of Technology Delhi Scalable Symbolic Execution: KLEE.
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.
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.
Lazy Annotation for Program Testing and Verification (Supplementary Materials) Speaker: Chen-Hsuan Adonis Lin Advisor: Jie-Hong Roland Jiang December 3,
Dynamic Symbolic Execution (aka, directed automated random testing, aka concolic execution) Slides by Koushik Sen.
CSE 331 SOFTWARE DESIGN & IMPLEMENTATION SYMBOLIC TESTING Autumn 2011.
Symstra: A Framework for Generating Object-Oriented Unit Tests using Symbolic Execution Tao Xie, Darko Marinov, Wolfram Schulte, and David Notkin University.
Symbolic Execution Suman Jana
A Test Case + Mock Class Generator for Coding Against Interfaces
Automatic Test Generation SymCrete
Example (C code) int double(int x) { return 2 * x; }
CUTE: A Concolic Unit Testing Engine for C
Presentation transcript:

Amal Khalil & Juergen Dingel Symbolic Execution Amal Khalil & Juergen Dingel CISC836: Models in Software Development: Methods, Techniques, and Tools Winter 2015

Outline Overview of Classical Symbolic Execution How it works Application of symbolic execution Challenges of symbolic execution Modern Symbolic Execution Techniques: Combining concrete and symbolic executions Concolic Testing Execution Generated Testing (EGT) KLEE Demo

Motivation Testing is a practical way for verifying programs. 3 Motivation Testing is a practical way for verifying programs. Manual testing is difficult and it requires knowledge of code and constant maintenance. Random testing is easy to perform but it is ineffective. It does not guarantee a full coverage of all program paths. Symbolic execution can systematically explore a large number of program paths. It is commonly used to derive the testing process and hence achieving higher path coverage.

4 Symbolic Execution A program analysis technique that allows the execution of programs in a parametric way using symbolic inputs to derive precise characterizations of their properties and their execution paths. Firstly introduced in the 70’s by Lori A. Clarke [1976] & James C. King [1976] for program testing. Since 2003, a lot of research efforts has been devoted to improve the effectiveness, the efficiency and the applicability of the traditional technique [Yang et al. 2014]. Examples of Symbolic Execution Tools: jCUTE, JPF (Java) KLEE (LLVM IR for C/C++) Pex (.NET Framework )

How does Symbolic Execution work? 5 How does Symbolic Execution work? The main idea is to substitute program inputs with symbolic values and then execute the program parametrically such that: The values of all program variables are computed as symbolic expressions over the symbolic input values; The execution can proceed along any feasible path.

How does Symbolic Execution work? 6 How does Symbolic Execution work? The result from the symbolic execution of a program is a tree-based structure called symbolic execution tree (SET). The nodes of a SET represent the symbolic program states and the edges represent the transitions between these states. Each program symbolic state consists of the set of program variables and their symbolic valuations, a program location, and a path constraint (PC) which is the the conjunction of all the logical constraints collected over the program variables to reach that program location. Decision procedures and SMT solvers are used to check the satisfiablity of each path constraint (PC). The set of path constraints computed by symbolic execution is used to enable various analysis, verification, and testing tasks. The paths of a SET characterize all the distinct execution paths of a program.

Constraints, Decision Procedures, and SMT Solvers 7 Constraints, Decision Procedures, and SMT Solvers Constraints X > Y Λ Y+X ≤ 10 (X, Y are called free variables) A solution of the constraint is a set of assignments, one for each free variable that makes the constraint satisfiable. {X = 3, Y=2} is a solution but {X = 6, Y=5} is not. Types of constraints Linear constraint (e.g., X > Y Λ Y+X ≤ 10) Non-linear constraint (e.g., X * Y < 100, X % 3 Λ Y > 10, and (X >> 3) < Y) Use of function symbols (e.g., f(X)> 10 Λ (forall a. f(a) = a + 10)) A decision procedure is a tool that can decide if a constraint is satisfiable. In general, checking constraint satisfiability is undecidable. A constraint solver is a tool that finds satisfying assignments for a constraint, if it is satisfiable. “A constraint solver is a program that computes solutions to logic formulas in a given logic.” Note: This page is taken from Saswat Anand’s slides on Symbolic Execution, 2009. http://www.cc.gatech.edu/~harrold/6340/cs6340_fall2009/Slides/SymExClass-09.pdf

>> Infeasible path 8 Example #1 Loc: 1 x: X, y: Y PC: true int foo (int x, int y){ 1: if (x > y) 2: x = x - y; 3: else 4: x = y - x; 5: if (x > 0) 6: x++; 7: else 8: x--; 9: return x; } Loc: 2 x: X, y: Y PC: X>Y 1: if(x>y) - then Loc: 4 x: X, y: Y PC: X<=Y 1: if(x>y) - else Loc: 5 x: X-Y, y: Y PC: X>Y 2: x = x - y; Loc: 5 x: Y-X, y: Y PC: X<=Y 4: x = y - x; Loc: 6 x: X-Y, y: Y PC: X>Y^X-Y>0 5: if(x>0) - then Loc: 8 x: X-Y, y: Y PC: X>Y^X-Y<=0 5: if(x>0) - else Loc: 6 x: Y-X, y: Y PC: X<=Y^Y-X>0 5: if(x>0) - then Loc: 8 x: Y-X, y: Y PC: X<=Y^Y-X<=0 5: if(x>0) - else Loc: 9 x: X-Y+1, y: Y PC: X>Y^X-Y>0 6: x++; Unsatisfiable PC >> Infeasible path Loc: 9 x: Y-X+1, y: Y PC: X<=Y^Y-X>0 6: x++; Loc: 9 x: Y-X-1, y: Y PC: X<=Y^Y-X<=0 8: x--; Path: 1, 2, 5, 6, 9 Test inputs: x: 7, y: 5 Path: 1, 4, 5, 6, 9 Test inputs: x: 3, y: 9 Path: 1, 4, 5, 8, 9 Test inputs: x: 1, y: 1

Example #1 9 Loc: 1 x: X, y: Y PC: true int foo (int x, int y){ 1: if (x > y) 2: x = x - y; 3: else 4: x = y - x; 5: if (x >= 0) 6: x++; 7: else 8: x--; 9: return x; } Loc: 2 x: X, y: Y PC: X>Y 1: if(x>y) - then Loc: 4 x: X, y: Y PC: X<=Y 1: if(x>y) - else Loc: 5 x: X-Y, y: Y PC: X>Y 2: x = x - y; Loc: 5 x: Y-X, y: Y PC: X<=Y 4: x = y - x; “Dead Code” Loc: 6 x: X-Y, y: Y PC: X>Y^X-Y>=0 5: if(x>0) - then Loc: 8 x: X-Y, y: Y PC: X>Y^X-Y<0 5: if(x>0) - else Loc: 6 x: Y-X, y: Y PC: X<=Y^Y-X>=0 5: if(x>0) - then Loc: 8 x: Y-X, y: Y PC: X<=Y^Y-X<0 5: if(x>0) - else Unsatisfiable PC >> Infeasible path Loc: 9 x: X-Y+1, y: Y PC: X>Y^X-Y>=0 6: x++; Unsatisfiable PC >> Infeasible path Loc: 9 x: Y-X+1, y: Y PC: X<=Y^Y-X>=0 6: x++;

Applications of Symbolic Execution 10 Applications of Symbolic Execution Test case generation Infeasible paths detection Invariants checking Bug findings Programs equivalence checking Regression analysis Others

Example #2 - [Cadar & Sen 2013] 11 Example #2 - [Cadar & Sen 2013] SS1 - Loc: 1 N: N1 PC: true void testme_inf(int N) { 1: int sum = 0; 2: while (N > 0) { 3: sum = sum + N; 4: N = sym_input(); 5: } } SS2 - Loc: 2 N: N1, sum: 0 PC: true 1: sum = 0; SS3 - Loc: 3 N: N1, sum: 0 PC: N1>0 2: while (N>0) - true Loc: 5 N: N1, sum: 0 PC: N1<=0 2: while (N>0) - false SS4 - Loc: 4 N: N1, sum: N1 PC: N1>0 3: sum = sum + N; SS5 - Loc: 2 N: N2, sum: N1 PC: N1>0 4: N = sym_input(); SS6 - Loc: 3 N: N2, sum: N1 PC: N1>0^N2>0 2: while (N>0) - true Loc: 5 N: N2, sum: N1 PC: N1>0^N2<=0 2: while (N>0) - false

Example #2 - [Cadar & Sen 2013] 12 Example #2 - [Cadar & Sen 2013] SS3 - Loc: 3 N: N1, sum: 0 PC: N1>0 2: while (N>0) - true SS1 - Loc: 1 N: N1 PC: true SS2 - Loc: 2 1: sum = 0; SS4 - Loc: 4 N: N1, sum: N1 SS5 - Loc: 2 N: N2, sum: N1 4: N = sym_input(); SS6 - Loc: 3 PC: N1>0^N2>0 3: sum = sum + N; void testme_inf(int N) { 1: int sum = 0; 2: while (N > 0) { 3: sum = sum + N; 4: N = sym_input(); 5: } } Loc: 5 N: N1, sum: 0 PC: N1<=0 2: while (N>0) - false Loc: 5 N: N2, sum: N1 PC: N1>0^N2<=0 2: while (N>0) - false

Example #2 - [Cadar & Sen 2013] SS4 - Loc: 4 N: N1, sum: N1 PC: N1>0 void testme_inf(int N) { 1: int sum = 0; 2: while (N > 0) { 3: sum = sum + N; 4: N = sym_input(); 5: } } 4: N = sym_input(); SS5 - Loc: 2 N: N2, sum: N1 PC: N1>0 2: while (N>0) - true Loc: 5 N: N2, sum: N1 PC: N1>0^N2<=0 2: while (N>0) - false SS6 - Loc: 3 N: N2, sum: N1 PC: N1>0^N2>0 SS7 - Loc: 4 N: N2, sum: N1+N1 PC: N1>0^N2>0 3: sum = sum + N; SS8 - Loc: 2 N: N3, sum: N1+N2 PC: N1>0^N2>0 4: N = sym_input(); SS9 - Loc: 3 N: N3, sum: N1+N2 PC: N1>0^N2>0^N3>0 2: while (N>0) - true Loc: 5 N: N3, sum: N1+N2 PC: N1>0^N2>0^N3<=0 2: while (N>0) - false

Example #2 - [Cadar & Sen 2013] SS6 - Loc: 3 N: N2, sum: N1 PC: N1>0^N2>0 2: while (N>0) - true SS4 - Loc: 4 N: N1, sum: N1 PC: N1>0 SS5 - Loc: 2 SS7 - Loc: 4 N: N2, sum: N1+N1 SS8 - Loc: 2 N: N3, sum: N1+N2 4: N = sym_input(); SS9 - Loc: 3 PC: N1>0^N2>0^N3>0 3: sum = sum + N; void testme_inf(int N) { 1: int sum = 0; 2: while (N > 0) { 3: sum = sum + N; 4: N = sym_input(); 5: } } Loc: 5 N: N2, sum: N1 PC: N1>0^N2<=0 2: while (N>0) - false Loc: 5 N: N3, sum: N1+N2 PC: N1>0^N2>0^N3<=0 2: while (N>0) - false

Example #2 - [Cadar & Sen 2013] SS7 - Loc: 4 N: N2, sum: N1+N1 PC: N1>0^N2>0 void testme_inf(int N) { 1: int sum = 0; 2: while (N > 0) { 3: sum = sum + N; 4: N = sym_input(); 5: } } 4: N = sym_input(); SS8 - Loc: 2 N: N3, sum: N1+N2 PC: N1>0^N2>0 2: while (N>0) - true Loc: 5 N: N3, sum: N1+N2 PC: N1>0^N2>0^N3<=0 2: while (N>0) - false SS9 - Loc: 3 N: N3, sum: N1+N2 PC: N1>0^N2>0^N3>0 SS10 - Loc: 4 N: N3, sum: N1+N2+N3 PC: N1>0^N2>0^N3>0 3: sum = sum + N; SS11- Loc: 2 N: N4, sum: N1+N2+N3 PC: N1>0^N2>0^N3>0 4: N = sym_input(); SS12 - Loc: 3 N: N4, sum: N1+N2+N3 PC: N1>0^N2>0^N3>0^N4>0 2: while (N>0) - true … Loc: 5 N: N4, sum: N1+N2+N3 PC: N1>0^N2>0^N3>0^N4<=0 2: while (N>0) - false

Challenges of Symbolic Execution 16 Challenges of Symbolic Execution Path explosion problem The number of feasible paths in a program grows exponentially with the size of the program and can be even infinite for programs with unbounded loops & recursion. Proposed solutions: Set upper bound for the number of iterations; Summarize loop effects; Use some abstraction criteria (e.g., subsumption) for pruning redundant paths and reducing the state space; Use heuristics for path finding to achieve some user-defined coverage criteria; Divide a program into independent parts and run the symbolic execution for each part in parallel. Path explosion problem for large programs Proposed solutions use heuristics for path finding to achieve some user-defined coverage criteria, or use abstraction for pruning redundant paths, or divide a program into independent parts and run the symbolic execution for each part in parallel. Infinite execution trees for programs with loops & recursion that have symbolic termination conditions Proposed solutions set upper bound for the number of iterations, summarize loop effects, or use some abstraction criteria to reduce the state space.

Example #2 - [Cadar & Sen 2013] 17 Example #2 - [Cadar & Sen 2013] SS1 - Loc: 1 N: N1 PC: true void testme_inf(int N) { 1: int sum = 0; 2: while (N > 0) { 3: sum = sum + N; 4: N = sym_input(); 5: } } SS2 - Loc: 2 N: N1, sum: 0 PC: true 1: sum = 0; SS3 - Loc: 3 N: N1, sum: 0 PC: N1>0 2: while (N>0) - true Loc: 5 N: N1, sum: 0 PC: N1<=0 2: while (N>0) - false SS4 - Loc: 4 N: N1, sum: N1 PC: N1>0 3: sum = sum + N; Solution #1: Set max-depth = 2 SS5 - Loc: 2 N: N2, sum: N1 PC: N1>0 4: N = sym_input(); SS6 - Loc: 3 N: N2, sum: N1 PC: N1>0^N2>0 2: while (N>0) - true Loc: 5 N: N2, sum: N1 PC: N1>0^N2<=0 2: while (N>0) - false

⊆ Example #2 - [Cadar & Sen 2013] Solution #2: Subsumption 18 Example #2 - [Cadar & Sen 2013] SS4 - Loc: 4 N: N1, sum: N1 PC: N1>0 Solution #2: Subsumption 4: N = sym_input(); SS5 - Loc: 2 N: N2, sum: N1 PC: N1>0 (N, sum) = {([-∞, + ∞], 1), ([-∞, + ∞], 2), ([-∞, + ∞], 3), …} Concretization of SS5 Subsumed by 2: while (N>0) - true SS9 - Loc: 5 N: N2, sum: N1 PC: N1>0^N2<=0 2: while (N>0) - false SS6 - Loc: 3 N: N2, sum: N1 PC: N1>0^N2>0 ⊆ 3: sum = sum + N; SS7 - Loc: 4 N: N2, sum: N1+N1 PC: N1>0^N2>0 (N, sum) = {([-∞, + ∞], 2), ([-∞, + ∞], 3), ([-∞, + ∞], 4), …} Concretization of SS8 “Do not explore a state that is subsumed by a previous one. For example, in a symbolic state a variable x could have any value that satisfies a constraint x > 0. If another execution path leads to an identical symbolic state except that the constraint for x is x > 5, the first symbolic state subsumes the second one (i.e., the first state represents all concrete states of the second symbolic state). To determine if a symbolic state has been visited before, a subsumption check by a constraint solver is needed. This can be computationally expensive especially if the constraints are complex.” 4: N = sym_input(); SS8 - Loc: 2 N: N3, sum: N1+N2 PC: N1>0^N2>0 SS9 - Loc: 3 N: N3, sum: N1+N2 PC: N1>0^N2>0^N3>0 2: while (N>0) - true Loc: 5 N: N3, sum: N1+N2 PC: N1>0^N2>0^N3<=0 2: while (N>0) - false

⊆ Example #2 - [Cadar & Sen 2013] Solution #2: Subsumption SS6 - Loc: 3 N: N2, sum: N1 PC: N1>0^N2>0 2: while (N>0) - true SS9 - Loc: 5 PC: N1>0^N2<=0 2: while (N>0) - false SS4 - Loc: 4 N: N1, sum: N1 PC: N1>0 SS5 - Loc: 2 SS7 - Loc: 4 N: N2, sum: N1+N1 SS8 - Loc: 2 N: N3, sum: N1+N2 4: N = sym_input(); Subsumed by SS3 - Loc: 3 N: N1, sum: 0 SS1 - Loc: 1 N: N1 PC: true SS2 - Loc: 2 1: sum = 0; 3: sum = sum + N; ⊆ (N, sum) = {([-∞, + ∞], 1), ([-∞, + ∞], 2), ([-∞, + ∞], 3), …} Concretization of SS5 (N, sum) = {([-∞, + ∞], 2), ([-∞, + ∞], 4), Concretization of SS8 19 Example #2 - [Cadar & Sen 2013] Solution #2: Subsumption SS10 - Loc: 5 N: N1, sum: 0 PC: N1<=0 2: while (N>0) - false

Challenges of Symbolic Execution 20 Challenges of Symbolic Execution Inability to solve very complex and non-linear constraints Proposed solutions: Use concretization (e.g., Concolic Symbolic Execution); Perform constraints simplification. Inability to handle external library calls Provide models to simulate/abstract the behavior of such external modules.

SE cannot handle symbolic value of z! 21 Example #3 - [Cadar & Sen 2013] Complex constraints External system/library calls void testme(int x, int y) { 1: int z = (y*y)%50; 2: if (z == x) { 3: if (x > y+10) { 4: abort(); //ERROR 5: } 6: } } void testme(int x, int y) { 1: int z = F(y); 2: if (z == x) { 3: if (x > y+10) { 4: abort(); //ERROR 5: } 6: } } Loc: 1 x: X, y: Y PC: true Loc: 1 x: X, y: Y PC: true 1: int z = (y*y)%50; 1: int z = F(y); Loc: 2 x: X, y: Y, z: (Y*Y)%50 PC: true Loc: 2 x: X, y: Y, z: F(Y) PC: true SE cannot handle symbolic value of z! >> Stuck!

Concolic Symbolic Execution 22 Concolic Symbolic Execution Novelty: Simultaneous Concrete & Symbolic Executions DART: Directed Automated Random Testing [Godefroid et al. 2005] Execution-Generated Testing (EGT) [Cadar et al. 2005] “Replace symbolic expression by concrete value when symbolic expression becomes unmanageable (e.g. non-linear).”

Overview of DART Example #3 - [Cadar & Sen 2013] 23 Overview of DART Example #3 - [Cadar & Sen 2013] Random testing alone is ineffective. Probability of reaching abort() is extremely low! Solution? Combine random testing & symbolic execution (twofold benefit). Improve test coverage of random testing Alleviate some of the imprecision in SE void testme(int x, int y) { 1: int z = 2 * y; 2: if (z == x) { 3: if (x > y + 10) 4: abort(); //ERROR 5: } } /* simple driver exercising testme() */ int main(){ int inp1 = random(); int inp2 = random(); testme(inp1, inp2); return 0; } “NOTE: whenever symbolic execution is stuck, static analysis becomes imprecise!”

Example #3 - [Cadar & Sen 2013] 24 Example #3 - [Cadar & Sen 2013] void testme(int x, int y) { 1: int z = 2 * y; 2: if (z == x) { 3: if (x > y + 10) 4: abort(); //ERROR 5: } } Loc: 1 x: X, y: Y PC: true Loc: 2 x: X, y: Y, z: 2*Y 1: int z = 2*y; Loc: 5 PC: 2*Y!=X 2: if(z==x) - false Loc: 3 x: X, y: Y, z: 2*Y PC: 2*Y==X 2: if(z==x) - true Loc: 5 PC: 2*Y==X^X<=Y+10 3: if(x>y+10) - false Test inputs: x = 22, y = 7 Path: 1, 2, 5 Test inputs: x = 2, y = 1 Path: 1, 2, 3, 5 Loc: 4 x: X, y: Y, z: 2*Y PC: 2*Y==X^X>Y+10 3: if(x>y+10) - true Solve: 2*Y==X Solution: x=2, y=1 Test inputs: x = 30, y = 15 Path: 1, 2, 3, 4 Abort>>ERROR Solve: 2*Y==X^X>Y+10 Solution: x=30, y=15

Example #3 - [Cadar & Sen 2013] 25 Example #3 - [Cadar & Sen 2013] void testme(int x, int y) { 1: int z = (y*y)%50; //int z = F(y); 2: if (z == x) { 3: if (x > y + 10) 4: abort(); //ERROR 5: } } Loc: 1 x: X, y: Y PC: true Loc: 2 x: X, y: 7, z: 49 1: int z = (y*y)%50; Loc: 5 PC: 49!=X 2: if(z==x) - false Loc: 3 x: X, y: 7, z: 49 PC: 49==X 2: if(z==x) - true Loc: 5 PC: 49==X^X>17 3: if(x>y+10) - true Test inputs: x = 22, y = 7 Path: 1, 2, 5 Test inputs: x = 49, y = 7 Path: 1, 2, 3, 7 Solve: 49==X Solution: x=49, y=7 Assume we can reason about linear constraints only. Cannot handle symbolic value of z! Do not stuck. Use concrete value z = 49 and proceed Take else branch with constraint 49 != X Solve 49 = X to take then branch Execute next run with x = 49 and y = 7 DART finds the error! Abort>>ERROR

KLEE LLVM Execution Engine [Cadar et al 2008] https://klee.github.io/ 26 KLEE Demo KLEE LLVM Execution Engine [Cadar et al 2008] https://klee.github.io/ Compiling C code into bytecode: llvm-gcc -I../../include/ --emit-llvm -c -g demo.c Running the bytecode using KLEE: klee -write-pcs -allow-external-sym-calls -emit-all-errors demo.o The test cases generated by KLEE are written in binary files with extension “.ktest”. We can read these test cases using the “ktest-tool” utility: ktest-tool --write-ints klee-last/test000001.ktest KLEE has a convenient library called “lkleeRuntest” for replaying a test case which replaces the call to “klee_make_symbolic” with a call to a function that assigns to the input the value stored in the “.ktest” file. To use this library, we need to link our “.c” file with the “lkleeRuntest” library and set the “KTEST_FILE” environment variable to point to the file name of the required test case: gcc -I../../include/ -L $LD_LIBRARY_PATH demo.c –lkleeRuntest KTEST_FILE=klee-last/test000001.ktest ./a.out

27 References [1] King, James C, "Symbolic execution and program testing", Communications of the ACM 19, 7 (1976), pp. 385--394. [2] Clarke, Lori A. "A system to generate test data and symbolically execute programs." Software Engineering, IEEE Transactions on 3 (1976): 215-222. [3] Khurshid, Sarfraz, Corina S. Păsăreanu, and Willem Visser. "Generalized symbolic execution for model checking and testing." Tools and Algorithms for the Construction and Analysis of Systems. Springer Berlin Heidelberg, 2003. 553-568. [4] Godefroid, Patrice, Nils Klarlund, and Koushik Sen. "DART: directed automated random testing." ACM Sigplan Notices. Vol. 40. No. 6. ACM, 2005. [5] Cadar, Cristian, and Dawson Engler. "Execution generated test cases: How to make systems code crash itself." Model Checking Software. Springer Berlin Heidelberg, 2005. 2-23. [6] Cadar, Cristian, Daniel Dunbar, and Dawson R. Engler. "KLEE: Unassisted and Automatic Generation of High-Coverage Tests for Complex Systems Programs." OSDI. Vol. 8. 2008. [7] Cadar, Cristian, and Koushik Sen. "Symbolic execution for software testing: three decades later." Communications of the ACM 56.2 (2013): 82-90. [8] Yang, Guowei, et al. "Directed incremental symbolic execution." ACM Transactions on Software Engineering and Methodology (TOSEM) 24.1 (2014): 3.