Working Towards the Verified Software Process

Numerous pieces of the software verification puzzle need to fit together in order to achieve that vision. First, there must be a programming language that gives some hope of specifying and implementing verifiable code (“assertive code”). Second, there needs to be a correct procedure for generating verification conditions (VCs) from this assertive code. Third, there must be one or more automated theorem provers to process the VCs and determine their validity or invalidity. Finally, it is essential that there is an interface for programmers to write their code and verify or debug it without forcing them to understand how particular automated theorem provers work. This dissertation covers the latter two of these topics using the Resolve language and verification framework. A common failing of most automated verification techniques is the inability to be truly automatic in all circumstances. Experience with proof assistants shows that they need to be “nudged” in the correct direction by an intervening human, in all but the simplest cases. Otherwise, the option is to use tools not geared to handle the rich mathematics used in the Resolve programming language. By using specialized decision procedures that take into account the known structure of the generated VCs, we strive to accomplish one of two possibilities for each VC: first, we hope to prove it outright; otherwise, we hope to simplify the VC to such an extent that another prover is able to handle it. We detail work on SplitDecision, a tool that simplifies VCs for ii Resolve. We further explain work that has helped to ensure SplitDecision is among the fastest and least memory intensive automated provers available, by introducing “lazy copying” to Resolve/C++ (in which SplitDecision is written), with specific work to maintain the value semantics integral to Resolve’s design. Sometimes (perhaps this is even the modal case) at least one VC is not proved because it is not valid. It is clear that the ways we present errors and debug code must be rethought in a verified software paradigm. This area of research has received little attention to date, so we lay out criteria for how to approach debugging, along with potential methods of doing so.

[1]  K. Rustan M. Leino,et al.  Loop Invariants on Demand , 2005, APLAS.

[2]  Burkhart Wolff,et al.  HOL-Boogie—An Interactive Prover-Backend for the Verifying C Compiler , 2009, Journal of Automated Reasoning.

[3]  Ida Eriksson,et al.  Extra, extra, read all about it. , 2011, Nature methods.

[4]  Paul B. Jackson,et al.  Using SMT solvers to verify high-integrity programs , 2007, AFM '07.

[5]  Angelos D. Keromytis,et al.  Countering code-injection attacks with instruction-set randomization , 2003, CCS '03.

[6]  Edsger W. Dijkstra,et al.  Chapter I: Notes on structured programming , 1972 .

[7]  Daniel Jackson,et al.  Elements of style: analyzing a software design feature with a counterexample detector , 1996, ISSTA '96.

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

[9]  Bruce W. Weide,et al.  Traditional assignment considered harmful , 2009, OOPSLA Companion.

[10]  Erica Mealy,et al.  BegBunch: benchmarking for C bug detection tools , 2009, DEFECTS '09.

[11]  Michiaki Tatsubori,et al.  Copy-on-write in the PHP language , 2009, POPL '09.

[12]  Carlo Ghezzi,et al.  Incremental Parsing , 1979, TOPL.

[13]  Shuvendu K. Lahiri,et al.  Back to the future: revisiting precise program verification using SMT solvers , 2008, POPL '08.

[14]  C. A. R. Hoare The Verifying Compiler, a Grand Challenge for Computing Research , 2005, VMCAI.

[15]  Alan J. Hu,et al.  Calysto: scalable and precise extended static checking , 2008, ICSE.

[16]  Henry G. Baker,et al.  Shallow binding in Lisp 1.5 , 1978, CACM.

[17]  A. D. Robison The Illinois functional programming interpreter , 1987, PLDI 1987.

[18]  Hai Lin,et al.  Encoding First Order Proofs in SMT , 2008, SMT@CAV.

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

[20]  Tobias Nipkow,et al.  The Isabelle Framework , 2008, TPHOLs.

[21]  Claudionor José Nunes Coelho,et al.  Beyond verification: Leveraging formal for debugging , 2009, 2009 46th ACM/IEEE Design Automation Conference.

[22]  Murali Sitaraman,et al.  On the Practical Need for Abstraction Relations to Verify Abstract Data Type Representations , 1997, IEEE Trans. Software Eng..

[23]  Stuart H. Zweben,et al.  Part I: the RESOLVE framework and discipline: a research synopsis , 1994, SOEN.

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

[25]  Ben Liblit,et al.  Tool Support for Proof Engineering , 2007, UITP@FLoC.

[26]  Natarajan Shankar,et al.  PVS: Combining Specification, Proof Checking, and Model Checking , 1996, FMCAD.

[27]  David Detlefs,et al.  Simplify: a theorem prover for program checking , 2005, JACM.

[28]  Manuel V. Hermenegildo,et al.  Integrated program debugging, verification, and optimization using abstract interpretation (and the Ciao system preprocessor) , 2005, Sci. Comput. Program..

[29]  Reiner Hähnle,et al.  Integrated and Tool-Supported Teaching of Testing, Debugging, and Verification , 2009, TFM.

[30]  Gregory Kulczycki,et al.  Reasoning about Procedure Calls with Repeated Arguments and the Reference-Value Distinction , 2003 .

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

[32]  Sarfraz Khurshid,et al.  Software assurance by bounded exhaustive testing , 2004, IEEE Transactions on Software Engineering.

[33]  Matt Kaufmann,et al.  An ACL2 Tutorial , 2008, TPHOLs.

[34]  John Matthews,et al.  Using Yices as an automated solver in Isabelle / HOL , 2008 .

[35]  Philip Wadler,et al.  Once upon a type , 1995, FPCA '95.

[36]  Bruce W. Weide,et al.  Copying and Swapping: Influences on the Design of Reusable Software Components , 1991, IEEE Trans. Software Eng..

[37]  Tim A. Wagner,et al.  Efficient and flexible incremental parsing , 1998, TOPL.

[38]  K. Rustan M. Leino,et al.  Declaring and checking non-null types in an object-oriented language , 2003, OOPSLA 2003.

[39]  Frank Piessens,et al.  VeriFast: Imperative Programs as Proofs , 2010 .

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

[41]  Greg Nelson,et al.  Simplification by Cooperating Decision Procedures , 1979, TOPL.

[42]  Crispan Cowan,et al.  StackGuard: Automatic Adaptive Detection and Prevention of Buffer-Overflow Attacks , 1998, USENIX Security Symposium.

[43]  Gila Kamhi,et al.  Efficient Debugging in a Formal Verification Environment , 2001, CHARME.

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

[45]  Nicholas Nethercote,et al.  Valgrind: a framework for heavyweight dynamic binary instrumentation , 2007, PLDI '07.

[46]  Stephen H. Edwards,et al.  Part II: specifying components in RESOLVE , 1994, SOEN.

[47]  Christoph Gladisch,et al.  Could We Have Chosen a Better Loop Invariant or Method Contract? , 2009, TAP@TOOLS.

[48]  Murali Sitaraman,et al.  DEET for Component-Based Software , 2004 .

[49]  Susan Horwitz,et al.  Protecting C programs from attacks via invalid pointer dereferences , 2003, ESEC/FSE-11.

[50]  Gregory Kulczycki,et al.  Reasoning about Software-Component Behavior , 2000, ICSR.

[51]  Bruce W. Weide,et al.  Part III: implementing components in RESOLVE , 1994, SOEN.

[52]  Bruce W. Weide,et al.  Part IV: RESOLVE components in Ada and C++ , 1994, SOEN.