Verifying concurrent programs: Refinement, synchronization, sequentialization

Designing and verifying concurrent programs is a notoriously challenging, time consuming, and error prone task, even for experts. This is due to the sheer number of possible interleavings of a concurrent program, all of which have to be tracked and accounted for in a formal proof. Inventing an inductive invariant that captures all interleavings of a low-level implementation is theoretically possible, but practically intractable. We develop a refinement-based verification framework that provides mechanisms to simplify proof construction by decomposing the verification task into smaller subtasks. In a first line of work, we present a foundation for refinement reasoning over structured concurrent programs. We introduce layered concurrent programs as a compact notation to represent multi-layer refinement proofs. A layered concurrent program specifies a sequence of connected concurrent programs, from most concrete to most abstract, such that common parts of different programs are written exactly once. Each program in this sequence is expressed as structured concurrent program, i.e., a program over (potentially recursive) procedures, imperative control flow, gated atomic actions, structured parallelism, and asynchronous concurrency. This is in contrast to existing refinement-based verifiers, which represent concurrent systems as flat transition relations. We present a powerful refinement proof rule that decomposes refinement checking over structured programs into modular verification conditions. Refinement checking is supported by a new form of modular, parameterized invariants, called yield invariants, and a linear permission system to enhance local reasoning. In a second line of work, we present two new reduction-based program transformations that target asynchronous programs. These transformations reduce the number of interleavings that need to be considered, thus reducing the complexity of invariants. Synchronization simplifies the verification of asynchronous programs by introducing the fiction, for proof purposes, that asynchronous operations complete synchronously. Synchronization summarizes an asynchronous computation as immediate atomic effect. Inductive sequentialization establishes sequential reductions that captures every behavior of the original program up to reordering of coarse-grained commutative actions. A sequential reduction of a concurrent program is easy to reason about since it corresponds to a simple execution of the program in an idealized synchronous environment, where processes act in a fixed order and at the same speed. Our approach is implemented the CIVL verifier, which has been successfully used for the verification of several complex concurrent programs. In our methodology, the overall correctness of a program is established piecemeal by focusing on the invariant required for each refinement step separately. While the programmer does the creative work of specifying the chain of programs and the inductive invariant justifying each link in the chain, the tool automatically constructs the verification conditions underlying each refinement step.

[1]  Maurice Herlihy,et al.  Linearizability: a correctness condition for concurrent objects , 1990, TOPL.

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

[3]  Lars Birkedal,et al.  Iris from the ground up: A modular foundation for higher-order concurrent separation logic , 2018, Journal of Functional Programming.

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

[5]  Rupak Majumdar,et al.  Why is random testing effective for partition tolerance bugs? , 2017, Proc. ACM Program. Lang..

[6]  Jan Smans,et al.  Verification of Concurrent Programs with Chalice , 2009, FOSAD.

[7]  Zhong Shao,et al.  Building certified concurrent OS kernels , 2019, Commun. ACM.

[8]  Thomas A. Henzinger,et al.  Reactive Modules , 1996, Proceedings 11th Annual IEEE Symposium on Logic in Computer Science.

[9]  Thomas A. Henzinger,et al.  Synchronizing the Asynchronous , 2018, CONCUR.

[10]  Constantin Enea,et al.  Verifying Visibility-Based Weak Consistency , 2019, ESOP.

[11]  Derek Dreyer,et al.  The future is ours: prophecy variables in separation logic , 2020, Proc. ACM Program. Lang..

[12]  Ernest J. H. Chang,et al.  An improved algorithm for decentralized extrema-finding in circular configurations of processes , 1979, CACM.

[13]  Ashutosh Gupta,et al.  Predicate abstraction and refinement for verifying multi-threaded programs , 2011, POPL '11.

[14]  Rupak Majumdar,et al.  Hitting Families of Schedules for Asynchronous Programs , 2016, CAV.

[15]  Edmund M. Clarke,et al.  Design and Synthesis of Synchronization Skeletons Using Branching Time Temporal Logic , 2008, 25 Years of Model Checking.

[16]  Serdar Tasiran,et al.  A calculus of atomic actions , 2009, POPL '09.

[17]  Kenneth L. McMillan,et al.  Ivy: safety verification by interactive generalization , 2016, PLDI.

[18]  Ilya Sergey,et al.  Programming and proving with distributed protocols , 2017, Proc. ACM Program. Lang..

[19]  Jakob Rehof,et al.  Context-Bounded Model Checking of Concurrent Software , 2005, TACAS.

[20]  Nobuko Yoshida,et al.  Distributed programming using role-parametric session types in go: statically-typed endpoint APIs for dynamically-instantiated communication structures , 2019, Proc. ACM Program. Lang..

[21]  AZADEH FARZAN,et al.  Reductions for safety proofs , 2019, Proc. ACM Program. Lang..

[22]  Kenneth L. McMillan,et al.  A Compositional Rule for Hardware Design Refinement , 1997, CAV.

[23]  Philippe Schnoebelen,et al.  Well-structured transition systems everywhere! , 2001, Theor. Comput. Sci..

[24]  Damien Zufferey,et al.  P: safe asynchronous event-driven programming , 2013, PLDI.

[25]  Roland Meyer,et al.  Robustness against Relaxed Memory Models , 2014, Software Engineering.

[26]  Ranjit Jhala,et al.  Verifying distributed programs via canonical sequentialization , 2017, Proc. ACM Program. Lang..

[27]  Randal E. Bryant,et al.  Concurrent programming , 1980, Operating Systems Engineering.

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

[29]  Robert W. Floyd,et al.  Assigning Meanings to Programs , 1993 .

[30]  Kenneth L. McMillan,et al.  Verification of an Implementation of Tomasulo's Algorithm by Compositional Model Checking , 1998, CAV.

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

[32]  Zvonimir Rakamaric,et al.  Delay-bounded scheduling , 2011, POPL '11.

[33]  Edmund M. Clarke,et al.  Compositional model checking , 1989, [1989] Proceedings. Fourth Annual Symposium on Logic in Computer Science.

[34]  Marieke Huisman,et al.  Future-based Static Analysis of Message Passing Programs , 2016, PLACES.

[35]  Rupak Majumdar,et al.  Rely/Guarantee Reasoning for Asynchronous Programs , 2015, CONCUR.

[36]  Serdar Tasiran,et al.  A mechanized refinement proof of the Chase–Lev deque using a proof system , 2018, Computing.

[37]  Shaz Qadeer,et al.  Refinement for Structured Concurrent Programs , 2020, CAV.

[38]  Jacob R. Lorch,et al.  Armada: low-effort verification of high-performance concurrent programs , 2020, PLDI.

[39]  Marieke Huisman,et al.  The VerCors Tool Set: Verification of Parallel and Concurrent Software , 2017, IFM.

[40]  Serdar Tasiran,et al.  Reasoning About TSO Programs Using Reduction and Abstraction , 2018, CAV.

[41]  D SchlichtingRichard,et al.  Using message passing for distributed programming: proof rules and disciplines , 1984 .

[42]  Butler W. Lampson,et al.  Verifying concurrent software using movers in CSPEC , 2018, OSDI.

[43]  Salvatore La Torre,et al.  Reducing Context-Bounded Concurrent Reachability to Sequential Reachability , 2009, CAV.

[44]  Viktor Vafeiadis Automatically Proving Linearizability , 2010, CAV.

[45]  Alexey Gotsman,et al.  Proving Linearizability Using Partial Orders , 2017, ESOP.

[46]  Nikolaj Bjørner,et al.  Cardinalities and universal quantifiers for verifying parameterized systems , 2016, PLDI.

[47]  Thomas A. Henzinger,et al.  MOCHA: Modularity in Model Checking , 1998, CAV.

[48]  Nikolaj Bjørner,et al.  Generalized, efficient array decision procedures , 2009, 2009 Formal Methods in Computer-Aided Design.

[49]  Constantin Enea,et al.  On the Completeness of Verifying Message Passing Programs under Bounded Asynchrony , 2018, CAV.

[50]  Shaz Qadeer,et al.  Layered Concurrent Programs , 2018, CAV.

[51]  Constantin Enea,et al.  Inductive sequentialization of asynchronous programs , 2020, PLDI.

[52]  Leslie Lamport,et al.  Specifying Systems: The TLA+ Language and Tools for Hardware and Software Engineers [Book Review] , 2002, Computer.

[53]  Stephen N. Freund,et al.  VerifiedFT: a verified, high-performance precise dynamic race detector , 2018, PPoPP.

[54]  Deian Stefan,et al.  Pretend synchrony: synchronous verification of asynchronous distributed programs , 2019, Proc. ACM Program. Lang..

[55]  Sriram K. Rajamani,et al.  The SLAM project: debugging system software via static analysis , 2002, POPL '02.

[56]  David Gries,et al.  A proof technique for communicating sequential processes , 1981, Acta Informatica.

[57]  Shmuel Sagiv,et al.  Paxos made EPR: decidable reasoning about distributed protocols , 2017, Proc. ACM Program. Lang..

[58]  Hassen Saïdi,et al.  Construction of Abstract State Graphs with PVS , 1997, CAV.

[59]  Cliff B. Jones,et al.  Specification and Design of (Parallel) Programs , 1983, IFIP Congress.

[60]  Madan Musuvathi,et al.  Iterative context bounding for systematic testing of multithreaded programs , 2007, PLDI '07.

[61]  Patrice Godefroid,et al.  Partial-Order Methods for the Verification of Concurrent Systems , 1996, Lecture Notes in Computer Science.

[62]  Eli Gafni,et al.  Understanding and verifying distributed algorithms using stratified decomposition , 1988, PODC '88.

[63]  Srinath T. V. Setty,et al.  IronFleet: proving practical distributed systems correct , 2015, SOSP.

[64]  Serdar Tasiran,et al.  Automated and Modular Refinement Reasoning for Concurrent Programs , 2015, CAV.

[65]  Peter Müller,et al.  Actor Services - Modular Verification of Message Passing Programs , 2016, ESOP.

[66]  Willem P. de Roever,et al.  A Proof System for Communicating Sequential Processes , 1980, ACM Trans. Program. Lang. Syst..

[67]  Philip Wadler,et al.  Linear Types can Change the World! , 1990, Programming Concepts and Methods.

[68]  Niklaus Wirth,et al.  Program development by stepwise refinement , 1971, CACM.

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

[70]  Nancy A. Lynch,et al.  Forward and Backward Simulations: I. Untimed Systems , 1995, Inf. Comput..

[71]  Dinghao Wu,et al.  KISS: keep it simple and sequential , 2004, PLDI '04.

[72]  Fred B. Schneider,et al.  Verifying Programs That Use Causally-Ordered Message-Passing , 1995, Sci. Comput. Program..

[73]  Thomas Ball,et al.  Finding and Reproducing Heisenbugs in Concurrent Programs , 2008, OSDI.

[74]  Thai Son Hoang,et al.  Rodin: an open toolset for modelling and reasoning in Event-B , 2010, International Journal on Software Tools for Technology Transfer.

[75]  Thomas A. Henzinger,et al.  Lazy abstraction , 2002, POPL '02.

[76]  Lauretta O. Osho,et al.  Axiomatic Basis for Computer Programming , 2013 .

[77]  Jean-Raymond Abrial,et al.  The B-book - assigning programs to meanings , 1996 .

[78]  Richard J. Lipton,et al.  Reduction: a method of proving properties of parallel programs , 1975, CACM.

[79]  Gerard J. Holzmann,et al.  The Model Checker SPIN , 1997, IEEE Trans. Software Eng..

[80]  Susan S. Owicki,et al.  Axiomatic Proof Techniques for Parallel Programs , 1975, Outstanding Dissertations in the Computer Sciences.

[81]  Peter W. O'Hearn,et al.  Resources, Concurrency and Local Reasoning , 2004, CONCUR.

[82]  Joseph Sifakis,et al.  Specification and verification of concurrent systems in CESAR , 1982, Symposium on Programming.

[83]  Krzysztof R. Apt,et al.  Formal Justification of a Proof System for Communicating Sequential Processes , 1983, JACM.

[84]  Rupak Majumdar,et al.  Randomized testing of distributed systems with probabilistic guarantees , 2018, Proc. ACM Program. Lang..

[85]  Cormac Flanagan,et al.  A type and effect system for atomicity , 2003, PLDI.

[86]  Stephen N. Freund,et al.  FastTrack: efficient and precise dynamic race detection , 2009, PLDI '09.

[87]  Serdar Tasiran,et al.  Tressa: Claiming the Future , 2010, VSTTE.

[88]  Jozef Hooman,et al.  Concurrency Verification: Introduction to Compositional and Noncompositional Methods , 2001, Cambridge Tracts in Theoretical Computer Science.

[89]  Ralph-Johan Back,et al.  Refinement Calculus: A Systematic Introduction , 1998 .

[90]  Ahmed Bouajjani,et al.  On Sequentializing Concurrent Programs , 2011, SAS.

[91]  Nissim Francez,et al.  Decomposition of Distributed Programs into Communication-Closed Layers , 1982, Sci. Comput. Program..

[92]  Josef Widder,et al.  Communication-Closed Asynchronous Protocols , 2019, CAV.

[93]  Nikolaj Bjørner,et al.  Z3: An Efficient SMT Solver , 2008, TACAS.

[94]  Ahmed Bouajjani,et al.  Bounded phase analysis of message-passing programs , 2012, International Journal on Software Tools for Technology Transfer.

[95]  Peter W. O'Hearn,et al.  RacerD: compositional static race detection , 2018, Proc. ACM Program. Lang..

[96]  Leslie Lamport,et al.  The part-time parliament , 1998, TOCS.

[97]  Thomas W. Reps,et al.  Reducing Concurrent Analysis Under a Context Bound to Sequential Analysis , 2008, CAV.

[98]  Patrick Cousot,et al.  Abstract interpretation: a unified lattice model for static analysis of programs by construction or approximation of fixpoints , 1977, POPL.

[99]  Thomas A. Henzinger,et al.  PSync: a partially synchronous language for fault-tolerant distributed algorithms , 2016, POPL.

[100]  Zhong Shao,et al.  Certified concurrent abstraction layers , 2018, PLDI.

[101]  Xi Wang,et al.  Verdi: a framework for implementing and formally verifying distributed systems , 2015, PLDI.

[102]  Constantin Enea,et al.  Proving Linearizability Using Forward Simulations , 2017, CAV.

[103]  Sérgio Vale Aguiar Campos,et al.  Symbolic Model Checking , 1993, CAV.

[104]  Serdar Tasiran,et al.  Verifying Robustness of Event-Driven Asynchronous Programs Against Concurrency , 2017, ESOP.

[105]  Rupak Majumdar,et al.  Asynchronous Liquid Separation Types , 2015, ECOOP.

[106]  Tracy Camp,et al.  Proof Rules for Flush Channels , 1993, IEEE Trans. Software Eng..

[107]  Sanjit A. Seshia,et al.  Systematic testing of asynchronous reactive systems , 2015, ESEC/SIGSOFT FSE.

[108]  Martín Abadi,et al.  The existence of refinement mappings , 1988, [1988] Proceedings. Third Annual Information Symposium on Logic in Computer Science.