Integrating Symbolic Execution, Debugging and Verification

In modern software development, almost all activities are centered around an integrated development environment (IDE). Besides the main use cases to write, execute and debug source code, an IDE serves also as front-end for other tools involved in the development process such as a version control system or an application lifecycle management. Independent from the applied development process, the techniques to ensure correct software are always the same. The general goal is to find defects as soon as possible, because the sooner a defect is found, the easier and cheaper it is to fix. In the first place, the programming language helps to prevent some kinds of defects. Once something is written, it is effective to review it not only to find defects, but also to increase its quality. Also tools which statically analyze the source code help to find defects automatically. In addition, testing is used to ensure that selected usage scenarios behave as expected. However, a test can only show the presence of a failure and not its absence. To ensure that a program is correct, it needs to be proven that the program complies to a formal specification describing the desired behavior. This is done by formal verification tools. Finally, whenever a failure is observed, debugging takes place to locate the defect. This thesis extends the software development tool suite by an interactive debugger based on symbolic execution, a technique to explore all feasible execution paths up to a given depth simultaneously. Such a tool can not only be used for classical debugging activities, but also during code reviews or in order to present results of an analysis based on symbolic execution. The contribution is an extension of symbolic execution to explore the full program behavior even in presence of loops and recursive method calls. This is achieved by integrating specifications in form of loop invariants and methods contracts into a symbolic execution engine. How such a symbolic execution engine based on verification proofs can be realized is presented as well. In addition, the presented Symbolic Execution Debugger (SED) makes the Eclipse platform ready for debuggers based on symbolic execution. Its functionality goes beyond that of traditional interactive debuggers. For instance, debugging can start directly at any method or statement and all program execution paths are explored simultaneously. To support program comprehension, program execution paths as well as intermediate states are visualized. By default, the SED comes with a symbolic execution engine implemented on top of the KeY verification system. Statistical evidence that the SED increases effectiveness of code reviews is gained from a controlled experiment. Another novelty of the SED is that arbitrary verification proofs can be inspected. Whereas traditional user interfaces of verification tools present proof states in a mathematical fashion, the SED analyzes the full proof and presents different aspects of it using specialized views. A controlled experiment gives statistical evidence that proof understanding tasks are more effective using the SED by comparing its user interface with the original one of KeY. The SED allows one to interact with the underlying prover by adapting code and specifications in an auto-active flavor, which creates the need to manage proofs directly within an IDE. A presented concept achieves this, by integrating a semi-automatic verification tool into an IDE. It includes several optimizations to reduce the overall proof time and can be realized without changing the verification tool. An optimal user experience is achieved only if all aspects of verification are directly supported within the IDE. Thus a thorough integration of KeY into Eclipse is presented, which for instance includes in addition to the proof management capabilities to edit JML specifications and to setup the needed infrastructure for verification with KeY. Altogether, a platform for tools based on symbolic execution and related to verification is presented, which offers a seamless integration into an IDE and furthers a usage in combination. Furthermore, many aspects, like the way the SED presents proof attempts to users, help to reduce the barrier of using formal methods.

[1]  Michael R. Lowry,et al.  Combining unit-level symbolic execution and system-level concrete execution for testing nasa software , 2008, ISSTA '08.

[2]  Frank Piessens,et al.  VeriFast: A Powerful, Sound, Predictable, Fast Verifier for C and Java , 2011, NASA Formal Methods.

[3]  Bor-Yuh Evan Chang,et al.  Boogie: A Modular Reusable Verifier for Object-Oriented Programs , 2005, FMCO.

[4]  Mark Weiser,et al.  Programmers use slices when debugging , 1982, CACM.

[5]  Karl J. Ottenstein,et al.  The program dependence graph in a software development environment , 1984, SDE 1.

[6]  Dieter Hutter,et al.  Development graphs - Proof management for structured specifications , 2006, J. Log. Algebraic Methods Program..

[7]  Bogdan Korel,et al.  A dynamic approach of test data generation , 1990, Proceedings. Conference on Software Maintenance 1990.

[8]  Koushik Sen DART: Directed Automated Random Testing , 2009, Haifa Verification Conference.

[9]  Karl N. Levitt,et al.  SELECT—a formal system for testing and debugging programs by symbolic execution , 1975 .

[10]  Frank S. de Boer,et al.  OpenJDK's Java.utils.Collection.sort() Is Broken: The Good, the Bad and the Worst Case , 2015, CAV.

[11]  Bil Lewis,et al.  Debugging Backwards in Time , 2003, ArXiv.

[12]  Frank Piessens,et al.  The VeriFast program verifier , 2008 .

[13]  Frank Piessens,et al.  Theoretical Aspects of Compositional Symbolic Execution , 2011, FASE.

[14]  Nikolai Tillmann,et al.  Pex-White Box Test Generation for .NET , 2008, TAP.

[15]  Thomas Thüm,et al.  Variability Hiding in Contracts for Dependent Software Product Lines , 2016, VaMoS.

[16]  Christoph Scheben,et al.  Program-level Specification and Deductive Verification of Security Properties , 2014 .

[17]  David C. Hoaglin,et al.  Some Implementations of the Boxplot , 1989 .

[18]  Reiner Hähnle,et al.  Generating Unit Tests from Formal Proofs , 2007, TAP.

[19]  Watts S. Humphrey,et al.  A discipline for software engineering , 2012, Series in software engineering.

[20]  Nikolai Tillmann,et al.  Parameterized Unit Testing with Pex , 2008, TAP.

[21]  Éric Tanter,et al.  Processing , 1988 .

[22]  Narciso Martí-Oliet,et al.  All About Maude - A High-Performance Logical Framework, How to Specify, Program and Verify Systems in Rewriting Logic , 2007, All About Maude.

[23]  Andreas Ibing,et al.  Parallel SMT-Constrained Symbolic Execution for Eclipse CDT/Codan , 2013, ICTSS.

[24]  Bernhard Beckert,et al.  Interactive Theorem Proving - Modelling the User in the Proof Process , 2015, Bridging@CADE.

[25]  J. Filliâtre,et al.  ACSL: ANSI/ISO C Specification Language , 2008 .

[26]  J. Stuart Aitken,et al.  An analysis of errors in interactive proof attempts , 2000, Interact. Comput..

[27]  Bernhard Beckert,et al.  Dynamic Logic , 2007, The KeY Approach.

[28]  Rudolf van Megen,et al.  Costs and benefits of early defect detection: experiences from developing client server and host applications , 1995, Software Quality Journal.

[29]  S. C. Kleene,et al.  Introduction to Metamathematics , 1952 .

[30]  Dawson R. Engler,et al.  KLEE: Unassisted and Automatic Generation of High-Coverage Tests for Complex Systems Programs , 2008, OSDI.

[31]  Klaus Havelund,et al.  Model checking programs , 2000, Proceedings ASE 2000. Fifteenth IEEE International Conference on Automated Software Engineering.

[32]  Frank Tip,et al.  A survey of program slicing techniques , 1994, J. Program. Lang..

[33]  Gordon J. Pace,et al.  StaRVOOrS: A Tool for Combined Static and Runtime Verification of Java , 2015, RV.

[34]  Michael E. Fagan Design and Code Inspections to Reduce Errors in Program Development , 1976, IBM Syst. J..

[35]  Bertrand Meyer,et al.  Applying 'design by contract' , 1992, Computer.

[36]  Gordon Fraser,et al.  Augmented dynamic symbolic execution , 2012, 2012 Proceedings of the 27th IEEE/ACM International Conference on Automated Software Engineering.

[37]  David Hovemeyer,et al.  Using Static Analysis to Find Bugs , 2008, IEEE Software.

[38]  Manu Sridharan,et al.  Thin slicing , 2007, PLDI '07.

[39]  Reiner Hähnle,et al.  Symbolic Execution Debugger (SED) , 2014, RV.

[40]  Jean-Christophe Filliâtre,et al.  Why3 - Where Programs Meet Provers , 2013, ESOP.

[41]  Andreas Zeller,et al.  Why Programs Fail: A Guide to Systematic Debugging , 2005 .

[42]  K. Rustan M. Leino,et al.  The boogie verification debugger , 2011, ICSE 2011.

[43]  Richard Bubel,et al.  PE-KeY: A Partial Evaluator for Java Programs , 2012, IFM.

[44]  Reiner Hähnle,et al.  Program Transformation Based on Symbolic Execution and Deduction , 2013, SEFM.

[45]  Richard Bubel,et al.  Dependency-Based Information Flow Analysis with Declassification in a Program Logic , 2015, ArXiv.

[46]  Mike Jackson,et al.  Interactive Proof Critics , 1999, Formal Aspects of Computing.

[47]  Christoph Scheben,et al.  Verification of Information Flow Properties of Java Programs without Approximations , 2011, FoVeOOS.

[48]  David R. Cok,et al.  SPEEDY: An Eclipse-based IDE for invariant inference , 2014, F-IDE.

[49]  Reiner Hähnle,et al.  Array Abstraction with Symbolic Pivots , 2016, Theory and Practice of Formal Methods.

[50]  Éric Tanter,et al.  Back to the Future: Omniscient Debugging , 2009, IEEE Software.

[51]  Till Mossakowski,et al.  Integrating HOL-CASL into the Development Graph Manager MAYA , 2002, FroCoS.

[52]  Mark A. Hillebrand,et al.  VCC: A Practical System for Verifying Concurrent C , 2009, TPHOLs.

[53]  Reiner Hähnle,et al.  Visualizing Unbounded Symbolic Execution , 2014, TAP@STAF.

[54]  Christoph Gladisch Verification-based software-fault detection , 2011 .

[55]  Eugene H. Spafford,et al.  Debugging with dynamic slicing and backtracking , 1993, Softw. Pract. Exp..

[56]  Bernhard Beckert,et al.  The KeY Platform for Verification and Analysis of Java Programs , 2014, VSTTE.

[57]  Guy L. Steele,et al.  The Java Language Specification , 1996 .

[58]  Rod M. Burstall,et al.  Program Proving as Hand Simulation with a Little Induction , 1974, IFIP Congress.

[59]  R. Geoff Dromey,et al.  From requirements to design: formalizing the key steps , 2003, First International Conference onSoftware Engineering and Formal Methods, 2003.Proceedings..

[60]  Muffy Calder,et al.  Interactive Theorem Proving: An Empirical Study of User Activity , 1998, J. Symb. Comput..

[61]  Mark Lillibridge,et al.  Extended static checking for Java , 2002, PLDI '02.

[62]  Bernhard Beckert,et al.  Reasoning and Verification: State of the Art and Current Trends , 2014, IEEE Intelligent Systems.

[63]  Christopher Svanefalk,et al.  KeYTestGen2: an automatic, verification-driven test case generator , 2014 .

[64]  K. Rustan M. Leino,et al.  Dafny: An Automatic Program Verifier for Functional Correctness , 2010, LPAR.

[65]  Peter Müller,et al.  Viper: A Verification Infrastructure for Permission-Based Reasoning , 2016, VMCAI.

[66]  Joshua Bloch Effective Java (2nd Edition) (The Java Series) , 2008 .

[67]  Reiner Hähnle,et al.  Abstract Interpretation of Symbolic Execution with Explicit State Updates , 2009, FMCO.

[68]  Nikolai Tillmann,et al.  XRT- Exploring Runtime for .NET Architecture and Applications , 2006, Electron. Notes Theor. Comput. Sci..

[69]  Dan Diaper,et al.  Desirable features of educational theorem provers - a cognitive dimensions viewpoint , 1999, PPIG.

[70]  Reiner Hähnle,et al.  Exploit Generation for Information Flow Leaks in Object-Oriented Programs , 2015, SEC.

[71]  Bernhard Beckert,et al.  Lessons Learned From Microkernel Verification -- Specification is the New Bottleneck , 2012, SSV.

[72]  Gunter Saake,et al.  Potential synergies of theorem proving and model checking for software product lines , 2014, SPLC.

[73]  K. Rustan M. Leino,et al.  The Dafny Integrated Development Environment , 2014, F-IDE.

[74]  Bernhard Beckert,et al.  Deductive Software Verification – The KeY Book , 2016, Lecture Notes in Computer Science.

[75]  Tobias Nipkow,et al.  A Proof Assistant for Higher-Order Logic , 2002 .

[76]  Paul Anderson,et al.  Software Inspection Using CodeSurfer , 2001 .

[77]  Daniel Bruns,et al.  Formal Specification with JML , 2014 .

[78]  Frank Piessens,et al.  A Quick Tour of the VeriFast Program Verifier , 2010, APLAS.

[79]  Jeannette M. Wing,et al.  A behavioral notion of subtyping , 1994, TOPL.

[80]  Dawson R. Engler,et al.  EXE: automatically generating inputs of death , 2006, CCS '06.

[81]  Michael E. Fagan Advances in software inspections , 1986, IEEE Transactions on Software Engineering.

[82]  James C. King,et al.  Symbolic execution and program testing , 1976, CACM.

[83]  Christoph Gladisch,et al.  Verification-Based Test Case Generation for Full Feasible Branch Coverage , 2008, 2008 Sixth IEEE International Conference on Software Engineering and Formal Methods.

[84]  K. Rustan M. Leino,et al.  The Spec# Programming System: An Overview , 2004, CASSIS.

[85]  Patrice Godefroid,et al.  Compositional dynamic test generation , 2007, POPL '07.

[86]  Edsger W. Dijkstra,et al.  The humble programmer , 1972, CACM.

[87]  David R. Cok,et al.  ESC/Java2: Uniting ESC/Java and JML , 2004, CASSIS.

[88]  Irina M ˘ ariuca,et al.  Towards a Formal Semantics-Based Technique for Interprocedural Slicing , 2014 .

[89]  David R. Cok,et al.  OpenJML: JML for Java 7 by Extending OpenJDK , 2011, NASA Formal Methods.

[90]  Kurt Stenzel,et al.  Structured Specifications and Interactive Proofs with KIV , 1998 .

[91]  Matthew B. Dwyer,et al.  Bogor: an extensible and highly-modular software model checking framework , 2003, ESEC/FSE-11.

[92]  David R. Cok,et al.  OpenJML: Software verification for Java 7 using JML, OpenJDK, and Eclipse , 2014, F-IDE.

[93]  Elvira Albert,et al.  jPET: An Automatic Test-Case Generator for Java , 2011, 2011 18th Working Conference on Reverse Engineering.

[94]  Mark David Weiser,et al.  Program slices: formal, psychological, and practical investigations of an automatic program abstraction method , 1979 .

[95]  Reiner Hähnle,et al.  An Interactive Verification Tool Meets an IDE , 2014, IFM.

[96]  Reiner Hähnle,et al.  Reuse in Software Verification by Abstract Method Calls , 2013, CADE.

[97]  Christoph Lüth,et al.  Proof General / Eclipse: A Generic Interface for Interactive Proof , 2005, IJCAI.

[98]  Steve Hanna,et al.  A Symbolic Execution Framework for JavaScript , 2010, 2010 IEEE Symposium on Security and Privacy.

[99]  Bernhard Beckert,et al.  Verifying Object-Oriented Programs with KeY: A Tutorial , 2006, FMCO.

[100]  Jooyong Yi,et al.  Bogor/Kiasan: A k-bounded Symbolic Execution for Checking Strong Heap Properties of Open Systems , 2006, 21st IEEE/ACM International Conference on Automated Software Engineering (ASE'06).

[101]  Adam A. Porter,et al.  Using symbolic evaluation to understand behavior in configurable software systems , 2010, 2010 ACM/IEEE 32nd International Conference on Software Engineering.

[102]  Kurt Stenzel,et al.  Reuse of Proofs in Software Verification , 1993, FSTTCS.

[103]  Brad A. Myers,et al.  Extracting and answering why and why not questions about Java program output , 2010, TSEM.

[104]  Jean-Raymond Abrial,et al.  Modeling in event-b - system and software engineering by Jean-Raymond Abrial , 2010, SOEN.

[105]  G. Gentzen Untersuchungen über das logische Schließen. I , 1935 .

[106]  Bernhard Beckert,et al.  A Usability Evaluation of Interactive Theorem Provers Using Focus Groups , 2014, SEFM Workshops.

[107]  Brad A. Myers,et al.  Designing the whyline: a debugging interface for asking questions about program behavior , 2004, CHI.

[108]  K. Rustan M. Leino,et al.  Fine-Grained Caching of Verification Results , 2015, CAV.

[109]  Sven Apel,et al.  Family-based deductive verification of software product lines , 2012, GPCE '12.

[110]  Zohar Manna,et al.  Towards automatic debugging of programs , 1975, Reliable Software.

[111]  Jim Gray,et al.  Why Do Computers Stop and What Can Be Done About It? , 1986, Symposium on Reliability in Distributed Software and Database Systems.

[112]  Nadia Polikarpova,et al.  AutoProof: auto-active functional verification of object-oriented programs , 2015, International Journal on Software Tools for Technology Transfer.

[113]  Ehud Shapiro,et al.  Algorithmic Program Debugging , 1983 .

[114]  Albert L. Baker,et al.  JML: A Notation for Detailed Design , 1999, Behavioral Specifications of Businesses and Systems.

[115]  Jorge A. Navas,et al.  TRACER: A Symbolic Execution Tool for Verification , 2012, CAV.

[116]  Corina S. Pasareanu,et al.  JPF-SE: A Symbolic Execution Extension to Java PathFinder , 2007, TACAS.

[117]  Bernhard Beckert,et al.  White-Box Testing by Combining Deduction-Based Specification Extraction and Black-Box Testing , 2007, TAP.

[118]  Benjamin Weiß,et al.  Deductive verification of object-oriented software: dynamic frames, dynamic logic and predicate abstraction , 2011 .

[119]  Steve McConnell,et al.  Code Complete, Second Edition , 2004 .

[120]  Reiner Hähnle,et al.  A visual interactive debugger based on symbolic execution , 2010, ASE '10.