A verification approach for system-level concurrent programs (original) (raw)

2008, Verified Software: Theories, …

https://doi.org/10.1007/978-3-540-87873-5_15

Sign up for access to the world's latest research

checkGet notified about relevant papers

checkSave papers to use in your research

checkJoin the discussion with peers

checkTrack your impact

Abstract

Though the verification of operating systems is an active research field, a verification method is still missing that provides both, the proximity to practically used programming languages such as C and a realistic model of concurrency, i.e. a model that copes with the granularity of atomic operations actually used in a target machine. Our approach serves as the foundation for

Mechanized Verification of Fine-grained Concurrent Programs

Efficient concurrent programs and data structures rarely employ coarse-grained synchronization mechanisms (i.e., locks); instead, they implement custom synchronization patterns via fine-grained primitives, such as compare-and-swap. Due to sophisticated interference scenarios between threads, reasoning about such programs is challenging and error-prone, and can benefit from mechanization. In this paper, we present the first completely formalized framework for mechanized verification of full functional correctness of fine-grained concurrent programs. Our tool is based on the recently proposed program logic FCSL. It is implemented as an embedded domain-specific language in the dependently-typed language of the Coq proof assistant, and is powerful enough to reason about programming features such as higher-order functions and local thread spawning. By incorporating a uniform concurrency model, based on state-transition systems and partial commutative monoids, FCSL makes it possible to build proofs about concurrent libraries in a thread-local, compositional way, thus facilitating scalability and reuse: libraries are verified just once, and their specifications are used ubiquitously in client-side reasoning. We illustrate the proof layout in FCSL by example, and report on our experience of using FCSL to verify a number of concurrent algorithms and data structures. 1 2015/2/6 2015/2/6 Lemma step W A B (e1 : ST W A) (e2 : A-> ST W B) i (k : cont B): verify i e1 (fun y m => verify m (e2 y) k)-> verify i (y <-e1; e2 y) k. ST is a type synonym for STsep, hiding its pre's and post's.

Generic tools for verifying concurrent systems

Science of Computer Programming, 2002

Despite the enormous strides made in automatic veri cation technology over the past decade and a half, tools such as model checkers remain relatively underused in the development of software. One reason for this is that the bewildering array of speci cation and veri cation formalisms complicates the development and adoption by users of relevant tool support. This paper proposes a remedy to this state of a airs in the case of nite-state concurrent systems by describing an approach to developing customizable yet e cient veri cation tools.

Verifiable concurrent programming using concurrency controllers

Proceedings. 19th International Conference on Automated Software Engineering, 2004., 2004

We present a framework for verifiable concurrent programming in Java based on a design pattern for concurrency controllers. Using this pattern, a programmer can write concurrency controller classes defining a synchronization policy by specifying a set of guarded commands and without using any of the error-prone synchronization primitives of Java. We present a modular verification approach that exploits the modularity of the proposed pattern, i.e., decoupling of the controller behavior from the threads that use the controller. To verify the controller behavior (behavior verification) we use symbolic and infinite state model checking techniques, which enable verification of controllers with parameterized constants, unbounded variables and arbitrary number of user threads. To verify that the threads use a controller in the specified manner (interface verification) we use explicit state model checking techniques, which allow verification of arbitrary thread implementations without any restrictions. We show that the correctness of the user threads can be verified using the concurrency controller interfaces as stubs, which improves the efficiency of the interface verification significantly. We also show that the concurrency controllers can be automatically optimized using the specific notification pattern. We demonstrate the effectiveness of our approach on a Concurrent Editor implementation which consists of 2800 lines of Java code with remote procedure calls and complex synchronization constraints.

Mechanized Verification of Fine-grained Concurrent Programs Accompanying tutorial and code commentary for PLDI 2015 artifact evaluation

2015

specification of a lock. What is a suitable abstract specification for a locking structure? To answer this question, we adopt the idea of specifying concurrent data structures via abstract predicates [1] and provide a lock interface in the form of two abstract procedures: lock and unlock. Every data structure, implementing the lock protocol, will require to provide the implementation of these procedures. The lock interface is parametrized by two abstract predicates, constraining some part of the state: is_lock and locked. The former denotes the fact that the part of state implements belongs to the locking protocol, while the latter one identifies that the lock is currently being locked by the current thread. Both predicates should satisfy a number of axioms, which are packaged into a dependent record in the section LockStruct (where the predicates are referred to as locked_op and is_lock_op). For instance, the following axiom expresses the lock’s mutual exclusion property: forall s ...

Modular verification of shared-memory concurrent system software

2011

Abstract Software is large, complex, and error-prone. According to the US National Institute of Standards and Technology, software bugs cost the US economy an estimated $60 billion each year. The trend in hardware design of switching to multi-core architectures makes software development even more complex. Cutting software development costs and ensuring higher reliability of software is of global interest and a grand challenge.

VCC: Contract-based modular verification of concurrent C

2009 31st International Conference on Software Engineering - Companion Volume, 2009

Most system level software is written in C and executed concurrently. Because such software is often critical for system reliability, it is an ideal target for formal verification. Annotated C and the Verified C Compiler (VCC) form the first modular sound verification methodology for concurrent C that scales to real-world production code. VCC is integrated in Microsoft Visual Studio and it comes with support for verification debugging: an explorer for counterexamples of failed proofs helps to find errors in code or specifications, and a prover log analyzer helps debugging proof attempts that exhaust available resources (memory, time). VCC is currently used to verify the core of Microsoft Hyper-V, consisting of 50,000 lines of system-level C code.

The effect of uncontrolled concurrency on model checking

Concurrency and Computation: Practice and Experience, 2008

Correctness of concurrent software is usually checked by techniques such as peer code reviews or code walkthroughs and testing. These techniques, however, are subject to human error, and thus do not achieve an in-depth verification of correctness. Model-checking techniques, which can systematically identify and verify every state that a system can enter, are a powerful alternative method for verifying concurrent systems. However, the usefulness of model checking is limited because the number of states for concurrent models grows exponentially with the number of processes in the system. This is often referred to as the 'state explosion problem.' Some processes are a central part of the software operation and must be included in the model. However, we have found that some exponential complexity results due to uncontrolled concurrency introduced by the programmer rather than due to the intrinsic characteristics of the software being modeled. We have performed tests on multimedia synchronization to show the effect of abstraction as well as uncontrolled concurrency using the Promela/SPIN model checker. We begin with a sequential model not expected to have exponential complexity but that results in exponential complexity. In this paper, we provide alternative designs and explain how uncontrolled concurrency can be removed from the code. synchronization and reliable communication protocols, and in these systems interaction among software/hardware modules should be coordinated to avoid unexpected failures. The verification of software and concurrent systems has been widely studied in . Also, verification methods used in different parts of the world have been surveyed . Several verification tools have been developed for verification of systems implemented in popular languages like Java . Some of the verification methods that are employed are code inspections/walkthroughs, pair programming, automated static analysis tools, coverage, capture/playback, model checking, and development testing tools . We are interested in model-checking verification since model checking is more rigorous than most other verification techniques because it can check all possible states a model can enter. There are usually three steps in model-checking verification: modeling, programming in the language of a model checker in order to implement a given model, and verification. Since all three steps are likely to be handled by a single person, we refer to a programmer as a person who models, implements, and verifies the model using a model checker. In this sense, a programmer is able to apply abstraction to the model as well as verify the model.

A comparison of runtime assertion checking and theorem proving for concurrent and distributed systems

Distributed systems play an essential role in society today. For example, distributed systems form the basis for critical infrastructure in different domains such as finance, medicine, aeronautics, telephony, and Internet services. It is of great importance that such systems work properly. However, quality assurance of distributed systems is non-trivial since they depend on unpredictable factors, such as different processing speeds of independent components. It is highly challenging to test such distributed systems after deployment under different relevant conditions. These challenges motivate frameworks combining precise modeling and analysis with suitable tool support. In particular, compositional verification systems allow the different components to be analyzed independently from their surrounding components. Thereby, it is possible to deal with systems consisting of many components. Object orientation is the leading framework for concurrent and distributed systems, recommended by the RM-ODP [15]. However, method-based communication between concurrent units may cause busy-waiting, as in the case of remote and synchronous method invocation, e.g., Java RMI [2]. Concurrent objects communicating by asynchronous method calls have been proposed as a promising framework to combine object-orientation and distribution in a natural manner. Each concurrent object encapsulates its own state and processor, and internal interference is avoided as at most one process is executing on an object at a time. Asynchronous method calls allow the caller to continue with its own activity without blocking while waiting for the reply, and a method call leads to a new process on the called object. The notion of futures [6, 19, 12, 20] improves this setting by providing a decoupling of the process invoking a method and the process reading the returned value. By sharing future identities, the caller enables other objects to wait for method results. However, futures complicate program analysis since programs become more involved compared to semantics with traditional method calls, and in particular local reasoning is a challenge. ABS [17] is a high-level imperative object-oriented modeling language, based on the concurrency and synchronization model of Creol [18]. It supports futures and concurrent objects with an asynchronous communication model suitable for loosely coupled objects in a distributed setting. In this work, we present our testing and verification tools for ABS programs. The execution of a distributed system can be represented by its communication history or trace; i.e., the sequence of observable communication events between system components [8, 14]. At any point in time the communication history abstractly captures the system state [10, 9]. In fact, traces are used in the semantics for full abstraction results (e.g., [16, 1]). The local history of an object reflects the communication visible to that object, i.e., between the object and its surroundings. A system may be specified by the finite initial segments of its communication histories, and a history invariant is a predicate which holds for all finite sequences in the set of possible histories, expressing safety properties [5]. In our reasoning system, we formalize object communication by an operational semantics

Back and Forth: Prophecy Variables for Static Verification of Concurrent Programs

2009

Several static proof systems have been developed over the years for verifying shared-memory multithreaded programs. These proof systems make use of auxiliary variables to express mutual exclusion or non-interference among shared variable accesses. Typically, the values of these variables summarize the past of the program execution; consequently, they are known as history variables. Prophecy variables, on the other hand, are

Loading...

Loading Preview

Sorry, preview is currently unavailable. You can download the paper by clicking the button above.

References (14)

  1. Leinenbach, D., Petrova, E.: Pervasive compiler verification: From verified pro- grams to verified systems. In: Systems Software Verification, Elsevier (2008) to appear
  2. Schirmer, N.: Verification of Sequential Imperative Programs in Isabelle/HOL. PhD thesis, TU Munich (2006)
  3. Leinenbach, D., Paul, W.J., Petrova, E.: Towards the formal verification of a C0 compiler: Code generation and implementation correctness. In: SEFM, IEEE Computer Society (2005) 2-12
  4. Beyer, S., Jacobi, C., Kröning, D., Leinenbach, D., Paul, W.J.: Putting it all together: Formal verification of the VAMP. STTT 8 (2006) 411-430
  5. Starostin, A., Tsyban, A.: Correct microkernel primitives. In: Systems Software Verification, Elsevier (2008) to appear
  6. Hillebrand, M.A., In der Rieden, T., Paul, W.J.: Dealing with I/O devices in the context of pervasive system verification. In: ICCD, IEEE (2005) 309-316
  7. Bevier, W.R.: Kit and the short stack. J. Autom. Reasoning 5 (1989) 519-530
  8. Hohmuth, M., Tews, H., Stephens, S.G.: Applying source-code verification to a microkernel: the VFiasco project. In: ACM SIGOPS European Workshop, ACM (2002) 165-169
  9. Tews, H.: Formal methods in the Robin project: Specification and verification of the Nova microhypervisor. In: C/C++ Verification Workshop, technical report ICIS-R07015, Radboud University Nijmegen (2007) 59-68
  10. Heiser, G., Elphinstone, K., Kuz, I., Klein, G., Petters, S.M.: Towards trustworthy computing systems: taking microkernels to the next level. Operating Systems Review 41 (2007) 3-11
  11. Shapiro, J.S., Weber, S.: Verifying the EROS confinement mechanism. In: IEEE Symposium on Security and Privacy. (2000) 166-176
  12. Shapiro, J., Doerrie, M.S., Northup, E., Sridhar, S., Miller, M.: Towards a verified, general-purpose operating system kernel. In: FM Workshop on OS Verification. Technical Report 0401005T-1, National ICT Australia (2004) 1-19
  13. Ni, Z., Yu, D., Shao, Z.: Using XCAP to certify realistic systems code: Machine context management. In: TPHOLs, Springer (2007) 189-206
  14. Hobor, A., Appel, A.W., Nardelli, F.Z.: Oracle semantics for concurrent separation logic. In: ESOP. Volume 4960 of LNCS., Springer (2008) 353-367

Runtime verification of concurrency-specific correctness criteria

International Journal on Software Tools for Technology Transfer, 2012

We give an overview of correctness criteria specific to concurrent shared-memory programs, and runtime verification techniques for verifying these criteria. We cover a spectrum of criteria, from ones focusing on low-level thread interference such a races to higher-level ones such as linearizability. We contrast these criteria in the context of runtime verification. We present the key ideas underlying the runtime verification techniques for these criteria, and summarize the state of the art. Finally, we discuss the issue of coverage for runtime verification for concurrency and present techniques that improve the set of covered thread interleavings.

Specifying and Verifying Concurrent C Programs with TLA+

Communications in Computer and Information Science, 2015

Verifying software systems automatically from their source code rather than modelling them in a dedicated language gives more confidence in establishing their properties. Here we propose a formal specification and verification approach for concurrent C programs directly based on the semantics of C. We define a set of translation rules and implement it in a tool (C2TLA+) that automatically translates C code into a TLA+ specification. The TLC model checker can use this specification to generate a model, allowing to check the absence of runtime errors and dead code in the C program in a given configuration. In addition, we show how translated specifications interact with manually written ones to: check the C code against safety or liveness properties; provide concurrency primitives or model hardware that cannot be expressed in C; and use abstract versions of translated C functions to address the state explosion problem. All these verifications have been conducted on an industrial case study, which is a part of the microkernel of the PharOS real-time system.

Concurrent software verification with states, events, and deadlocks

Formal Aspects of Computing, 2005

We present a framework for model checking concurrent software systems which incorporates both states and events. Contrary to other state/event approaches, our work also integrates two powerful verification techniques, counterexample-guided abstraction refinement and compositional reasoning. Our specification language is a state/event extension of linear temporal logic, and allows us to express many properties of software in a concise and intuitive manner. We show how standard automata-theoretic LTL model checking algorithms can be ported to our framework at no extra cost, enabling us to directly benefit from the large body of research on efficient LTL verification.

Design for verification for concurrent and distributed programs

2005

Design for Verification for Concurrent and Distributed Programs by Aysu Betin-Can In this dissertation we present a design for verification (DFV) approach that embeds intentions of developers into software and makes software systems amenable to automated verification; hence, making the automated verification techniques scalable to large systems. In this DFV approach, we use 1) behavioral interfaces that isolate the behavior and enable modular verification, 2) an assume-guarantee style verification strategy that separates verification of the behavior from the verification of the conformance to the interface specifications, 3) a general model checking technique for interface verification, and 4) domain specific and specialized verification techniques for behavior verification. We realize our DFV approach for concurrent programming by introducing the concurrency controller pattern. We aim to eliminate synchronization errors in concurrent Java programs. We use the Action Language Verifier to verify the concurrency controller behaviors by an automated translation from their Java implementations. We have applied this framework to two software systems: a concurrent text editor and a safety critical air traffic control software called TSAFE. To demonstrate the applicability of our DFV approach to another application domain, we introduce the peer controller pattern for asynchronously communicating viii web services. Our goal is both to analyze properties of interactions among the participating peers and to validate the conformance of peer implementations to their behavioral specifications. We use the SPIN model checker to verify the interaction properties. We adapt synchronizability analysis to enable behavior verification with respect to unbounded asynchronous communication queues. We extend this approach with an hierarchical interface model for compact representation of peer interfaces. We use the Java PathFinder for interface verification in both application domains. We present techniques for thread isolation which improve the efficiency of interface verification.

VYRD: verifYing concurrent programs by runtime refinement-violation detection

2005

We present a runtime technique for checking that a concurrentlyaccessed data structure implementation, such as a file system or the storage management module of a database, conforms to an executable specification that contains an atomic method per data structure operation. The specification can be provided separately or a non-concurrent, "atomized" interpretation of the implementation can serve as the specification. The technique consists of two phases. In the first phase, the implementation is instrumented in order to record information into a log during execution. In the second, a separate verification thread uses the logged information to drive an instance of the specification and to check whether the logged execution conforms to it. We paid special attention to the general applicability and scalability of the techniques and to minimizing their concurrency and performance impact. The result is a lightweight verification method that provides a significant improvement over testing for concurrent programs.

Run-Time Verification of Optimistic Concurrency

Lecture Notes in Computer Science, 2010

Assertion based specifications are not suitable for optimistic concurrency where concurrent operations are performed assuming no conflict among threads and correctness is cast in terms of the absence or presence of conflicts that happen in the future. What is needed is a formalism that allows expressing constraints about the future. In previous work, we introduced tressa claims and incorporated prophecy variables as one such formalism. We investigated static verification of tressa claims and how tressa claims improve reduction proofs.

Modular verification of multithreaded programs

Theoretical Computer Science, 2005

Multithreaded software systems are prone to errors due to the difficulty of reasoning about multiple interleaved threads operating on shared data. Static checkers that analyze a program's behavior over all execution paths and all thread interleavings are a powerful approach to identifying bugs in such systems. In this paper, we present Calvin, a scalable and expressive static checker for multithreaded programs based on automatic theorem proving. To handle realistic programs, Calvin performs modular checking of each procedure called by a thread using specifications of other procedures and other threads. Our experience applying Calvin to several real-world programs indicates that Calvin has a moderate annotation overhead and can catch common defects in multithreaded programs, such as synchronization errors and violations of data invariants.

Assume-Guarantee Verification of Concurrent Systems

2009

Process algebras are a set of mathematically rigourous languages with well defined semantics that permit modelling behaviour of concurrent and communicating systems. Verification of concurrent systems within the process algebraic approach can be performed by checking that processes enjoy properties described by some temporal logic’s formulae. In this paper we present a formal framework that permits verifying properties of concurrent and communicating systems by using an assumption-guarantee approach. Each system component is not considered in isolation, but in conjunction with assumptions about the context of the component. In the paper we introduce a sound and complete proof system that permits verifying whether a process, when it is executed in an environment for which we provide some assumptions, satisfies a given formula. It is also ensured that property satisfaction is preserved whenever the context is partially instantiated (implemented) as a concrete process that verifies the assumptions we have for the environment.

Verifying multi-threaded software using smt-based context-bounded model checking

2011

We describe and evaluate three approaches to model check multi-threaded software with shared variables and locks using bounded model checking based on Satisfiability Modulo Theories (SMT) and our modelling of the synchronization primitives of the Pthread library. In the lazy approach, we generate all possible interleavings and call the SMT solver on each of them individually, until we either find a bug, or have systematically explored all interleavings. In the schedule recording approach, we encode all possible interleavings into one single formula and then exploit the high speed of the SMT solvers. In the underapproximation and widening approach, we reduce the state space by abstracting the number of interleavings from the proofs of unsatisfiability generated by the SMT solvers. In all three approaches, we bound the number of context switches allowed among threads in order to reduce the number of interleavings explored. We implemented these approaches in ESBMC, our SMT-based bounded model checker for ANSI-C programs. Our experiments show that ESBMC can analyze larger problems and substantially reduce the verification time compared to stateof-the-art techniques that use iterative context-bounding algorithms or counter-example guided abstraction refinement.

Formal verification of microprocessors

Proceedings of the Fourth Annual Conference on Computer Assurance, 'Systems Integrity, Software Safety and Process Security, 1989

We present a general method for formally verifying the correctness of microprocessor designs. The abstract level specification of the processor defines the effect of every instruction in terms of a suitably chosen programmer's model of the processor. The concrete level specification gives a description of the design of the processor a t a synchronous level by defining the behavior over a single microcycle. We develop a general criterion of correctness to relate the two levels of behavior of the processor. We illustrate the application of our method to a simple processor, Simple, and a larger realistic processor MiniCayuga, which uses instruction pipelining. Both the designs have been completely verified using an applicative language based verification system Clio.