220 likes | 374 Views
Symbolic Execution with Mixed Concrete-Symbolic Solving Corina Pasareanu 1 , Neha Rungta 2 and Willem Visser 3 1 Carnegie Mellon, 2 SGT Inc./NASA Ames 3 University of Stellenbosch. Symbolic Execution. Program analysis technique King [Comm. ACM 1976] , Clarke [IEEE TSE 1976 ]
E N D
Symbolic Execution with Mixed Concrete-Symbolic Solving Corina Pasareanu1, Neha Rungta2 and Willem Visser3 1Carnegie Mellon, 2SGT Inc./NASA Ames 3University of Stellenbosch
Symbolic Execution • Program analysis technique • King [Comm. ACM 1976] , Clarke [IEEE TSE 1976] • Executes a program on symbolic inputs • Maintains path condition (PC) – checked for satisfiablity with decision procedures • Received renewed interest in recent years due to • Algorithmic advances • Increased availability of computational power and decision procedures • Applications: • Test-case generation, error detection, … • Tools, many open-source • UIUC: CUTE, jCUTE, Stanford: EXE, KLEE, UC Berkeley: CREST, BitBlaze • Microsoft’s Pex, SAGE, YOGI, PREfix • NASA’s Symbolic (Java) Pathfinder • IBM’s Apollo, Parasoft’s testing tools etc.
void test(int x, int y) { if (x > 0) { if (y == hash(x)) S0; else S1; if (x > 3 && y > 10) S3; else S4; } } S0, S1, S3, S4 = statements we wish to cover Symbolic Execution
void test(int x, int y) { if (x > 0) { if (y == hash(x)) S0; else S1; if (x > 3 && y > 10) S3; else S4; } } S0, S1, S3, S4 = statements we wish to cover Symbolic Execution Can not handle it! Solution: Mixed concrete-symbolic solving Assume hash is native or can not be handled by decision procedure
Mixed Concrete-Symbolic Solving //hash(x)=10*x Example Mixed concrete-symbolic solving: all paths covered Predicted path “S0;S4” != path taken “S1;S4” EXE results: stmt “S3” not covered DART results: path “S0;S4” not covered
Mixed Concrete-Symbolic Solving • Use un-interpreted functions for external library calls • Split path condition PC into: • simplePC– solvable constraints • complexPC– non-linear constraints with un-interpreted functions • Solve simplePC • Use obtained solutions to simplify complexPC • Check the result again for satisfiability
Mixed Concrete-Symbolic Solving Assume hash(x) = 10 *x: PC: X>3 ∧ Y>10 ∧ Y=hash(X) simplePCcomplexPC Solve simplePC Use solution X=4 to compute h(4)=40 Simplify complexPC: Y=40 Solve again: simplified PC: X>3 ∧Y>10 ∧ Y=40 Satisfiable!
Symbolic Execution void test(int x, int y) { if (x > 0) { if (y == hash(x)) S0; else S1; if (x > 3 && y > 10) S3; else S4; } } int hash(x) { if (0<=x<=10) return x*10; else return 0; } PC: true PC: X<=0 PC: X>0 Solve X>0 hash(1)=10 Check X>0 & Y=10 … PC: X>0 & Y=hash(X) S0 PC: X>0 & X<=3 & Y=hash(X) S4 PC: X>3 & Y>10 & Y=hash(X) S3 Solve X>3 & Y>10 hash(4)=40 Check X>3 & Y>10 & Y=40
Potential for Unsoundness test (int x, int y) { if (x>=0 && x>y && y == x*x) S0; else S1; } Not Reachable PC:X>=0 & X > Y & Y = X*X S0 Must add constraints on the solutions back into simplified PC simplePC X>=0 & X>Y complexPC Y = X*X X=0, Y=-1 Y=0*0=0 X>=0 & X>Y & Y=0 & X=0 simplified PC X>=0 & X>Y & Y=0 Not SAT! Is SAT which impliesS0 is Reachable! DART/Concolic will diverge instead
Directed Automated Random Testing (DART) Godefroid, Klarlund and Sen 2005 or Concolic Execution • Collects path conditions along concrete executions • Negates constraints on the PC after a run and • Executes again with the newly found solutions • Can overcome the weaknesses of classic symbolic execution
X>0 & Y!=10 & X>3 void test(int x, int y) { if (x > 0) { if (y == hash(x)) S0; else S1; if (x > 3 && y > 10) S3; else S4; } } native int hash(x) { if (0<=x<=10) return x*10; else return 0; } test(1,0) test(4,0) X > 0 X > 0 X > 0 & Y != 40 S1 X > 0 & Y != 10 S1 X>0 & Y!=40 & X>3 & Y<= 10 S4 X>0 & Y!=10 & X<=3 S4 DART/Concolic Execution
X>0 & Y!=40 & X>3 & Y>10 X>0 & Y=40 & X>3 & Y>10 test(4,11) test(4,40) void test(int x, int y) { if (x > 0) { if (y == hash(x)) S0; else S1; if (x > 3 && y > 10) S3; else S4; } } native int hash(x) { if (0<=x<=10) return x*10; else return 0; } X > 0 X > 0 X > 0 & Y != 40 S1 X > 0 & Y = 40 S0 X>0 & Y!=40 & X>3 & Y>10 S3 X>0 & Y=40 & X>3 & Y>10 S3 DART/Concolic Execution
X>0 & Y=40 & X<=3 & Y>10 void test(int x, int y) { if (x > 0) { if (y == hash(x)) S0; else S1; if (x > 3 && y > 10) S3; else S4; } } native int hash(x) { if (0<=x<=10) return x*10; else return 0; } test(1,40) X > 0 X > 0 & Y != 10 S1 Divergence! Aimed to get S0;S4 But reached S1;S4 X>0 & Y!=10 & X<=3 S4 DART/Concolic Execution
Mixed Concrete-Symbolic Solving vs DART • Both incomplete • Incomparable in power (see paper) • Mixed concrete-symbolic solving can handle only “pure”, side-effect free functions • DART does not have the limitation; will likely diverge
Addressing Incompleteness: 3 Heuristics Incremental Solving User Annotations Random Solving
Incremental Solving void test(int x, int y) { if (x > 0) { if (y == hash(x)) S0; else S1; if (y > 10) S3; else S4; } } int hash(x) { if (0<=x<=10) return x*10; else return 0; } PC: true PC: X<=0 PC: X>0 Solve X>0 hash(1)=10 Check X>0 & Y=10 … PC: X>0 & Y=hash(X) S0 PC: X>0 & X<=3 & Y=hash(X) S4 PC: X>0 & Y>10 & Y=hash(X) S3 Solve X>0 & Y>10 Solution: X=1 hash(1)=10 Check X>0 & Y>10 & Y=10 Not SAT! Get another solution: Solution: X=2 hash(2)=20 Check X>0 & Y>10 & Y=20 SAT!
User Annotations @Partition({“x>3”,”x<=3”}) void test(int x, int y) { if (x > 0) { if (y == hash(x)) S0; else S1; if (y > 10) S3; else S4; } } int hash(x) { if (0<=x<=10) return x*10; else return 0; } PC: true PC: X<=0 PC: X>0 Solve X>0 hash(1)=10 Check X>0 & Y=10 … PC: X>0 & Y=hash(X) S0 PC: X>0 & X<=3 & Y=hash(X) S4 PC: X>0 & Y>10 & Y=hash(X) S3 Solve X>0 & Y>10 & X>3 Hash(4)=40 Check X>0 & Y>10 & Y=40 SAT! Add user partitions one at a time
Random Solving • Pick solutions randomly from the solution space • Current implementation only picks randomly if the solution space is completely unconstrained
Implementation Mixed Concrete-Symbolic Solving Custom Listeners on SPF Symbolic PathFinderSPF Symbolic Execution Extension for JPF (jpf-symbc) Model Checker for JavaOpen Source http://babelfish.arc.nasa.gov/trac/jpf Java PathFinder Experience • TSAFE (Tactical Separation Assisted Flight Environment) • Apollo Lunar Pilot • Example PC: 37 constraints in simplePC and 6 in complexPC
Related Work • Tools that perform mixture of concrete and symbolic execution • EXE, DART, CUTE, PEX, SAGE, … • “Higher order test generation” – P. Godefroid [PLDI’11] • Uses combination of validity checking and un-interpreted functions • Generates tests from validity proofs • Implementation challenge
Conclusions and Future Work • Mixed concrete-symbolic solving to address problems with classic symbolic execution • Handling native libraries • Incomplete decision procedures • Open source implementation for Java • Future Work • More experiments • More heuristics • Handle data structures executed outside symbolic execution • Use JPF’s serialization