Checking software in this way has achieved some success: for example, de- vice drivers, garbage collectors and libraries implementing data structures can be veriﬁed. Well-known abstraction methods include interval analysis, pred- icate abstraction [ 2 ], shape analysis [ 16 ], abstraction by linear programming and various pointer analyses e.g. [ 19 ]. But although each of these methods works well for particular classes of programs and properties, all have “blind spots” where they are ineﬀective. Therefore it remains the case that “real” (applications) programs as written by ordinary programmers are beyond the scope of veriﬁcation. The problem is that designing abstraction schemes is diﬃcult: retaining too much irrelevant information results in high computa- tional cost, but if relevant facts are thrown away it will not be possible to verify the desired property.
We illustrate the usefulness and applicability of these functionalities in a case study. We apply the CVJ framework, along with the tool Joana [17, 18], which allows for the fully automatic verification of noninterference properties of Javaprograms, to establish cryptographic privacy properties of a non-trivial cloud storage application, where clients can store private information on a remote server. The cloud storage system makes use of all cryptographic primitives considered in this paper, and hence, the code of these functionalities is included in the verified program. We note that, except for a much simpler Java program analyzed in , there has been no other verification effort that establishes cryptographic security guarantees of Javaprograms.
User interaction during proof search. The KeY prover attempts to automate proof search as much as possible, but its also supports user interaction to guide the proof process. Proofs for valid formulas are often, but not always found au- tomatically. For example, if complex quantifier instantiations are required, proof search may fail. When automated proof search fails, the user can apply inference rules interactively in a stepwise manner, as described above. The problem is that after a failed automated verification attempt, the user may be confronted with an intermediate proof object that is difficult to understand, because the automatic proof strategy tends to produce normal forms that are hard to read. This led us to pursue a semi-automated proof style where the user does not apply every step manually, but interacts with the automated strategy only at certain points of interest. KeY provides composite interaction steps, so-called strategy macros, that combine the application of basic deduction steps to achieve a specific pur- pose. The available strategy macros in KeY include: Finish symbolic execution symbolically executes Javaprograms in modalities. Propositional expansion ap- plies only propositional rules. Close provable goals closes any open goal that is automatically provable, but does not touch goals where no automatic proof is found. The strategy macro Autopilot applies these three substrategies in this order. It divides the proof obligation into small subcases and thus guides the user to those points of the specification for which the automated proof failed.
We introduce the temporal logic HAWK and its supporting tool for runtime verification of Javaprograms. A monitor for a HAWK for- mula checks if a finite trace of program events satisfies the formula. HAWK is a programming-oriented extension of the rule-based EA- GLE logic that has been shown capable of defining and implement- ing a range of finite trace monitoring logics, including future and past time temporal logic, metric (real-time) temporal logics, inter- val logics, forms of quantified temporal logics, extended regular expressions, state machines, and others. Monitoring is achieved on a state-by-state basis avoiding any need to store the input trace. HAWK extends EAGLE with constructs for capturing parameterized program events such as method calls and method returns. Param- eters can be executing thread, the objects that methods are called upon, arguments to methods, and return values. HAWK allows one to refer to these in formulae. The tool synthesizes monitors from formulae and automates program instrumentation.
In , Küsters et al. have proposed a general framework for establishing computa- tional indistinguishability properties for J AVA (-like) programs using program analysis tools that can check (standard) noninterference properties  for J AVA programs. Sev- eral such tools exist, including Joana , KeY , a tool based on Maude , and Jif [19,21]. However, these tools cannot deal with cryptography directly. In particular, they cannot deal with probabilities and the noninterference properties that they prove are w.r.t. unbounded adversaries, rather than probabilistic polynomially bounded ad- versaries. For example, if a message is encrypted and the ciphertext is given to the adversary, the tools consider this to be an illegal information flow (or a declassifica- tion), because a computationally unbounded adversary could decrypt the message. This problem has long been observed in the literature (see, e.g.,  and references therein). ? This work was supported by the German National Science Foundation (DFG) under projects
Veriﬁcation of distributed programs continues to be an im- portant ﬁeld. The industry standard for communication in distributed programs is the MPI standard. Although much work has been published concerning the veriﬁca- tion of MPI-based programs, little work has been done towards veriﬁcation of its Java counterpart: MPJ. This paper presents the design of a tool that can translate Java using MPJ to a corresponding model checker model. The main focus is to abstract the control ﬂow of MPJ logic from the Java program, and verifying that with readily available model checkers. In order to achieve this, we present the design of a three-step method that is required to go from Java source to a Promela model, the input language for the SPIN model checker.
Many program analysis tools can deal only with closed Javaprograms. The systems we want to analyze are, how- ever, open, because they interact with a network or use some libraries that we do not (have to) trust, and hence, do not have to analyze. In our setting, the network and such libraries are simply considered to be part of the environment (the adversary). As part of our framework, we therefore also propose proof techniques that help program analysis tools to deal with these kinds of open systems, and in particular, to prove non-interference properties about these systems. These techniques are used in our case study (see below), but they are rather general, and hence, relevant beyond our case study. Since we use public-key encryption in our case study, we also propose an ideal functionality for public-key encryption coded in Jinja+, in the spirit of similar functionalities in the simulation-based approach (see, e.g., , ), and prove that it can be realized with any IND-CCA2-secure public- key encryption scheme. This result is needed whenever a Java system is analyzed that uses public-key encryption, and hence, is relevant beyond our case study. We note that the formulation of our ideal functionality is more restricted than the one in the cryptographic literature in that corruption is
ming, especially in the Java programming language, is growing rapidly in popularity. The additional complex- ity and inherent non-determinism of distributed systems makes understanding and reasoning about them extremely difficult. Moreover, testing such systems is problematic since, not only are there many more alternatives to ex- plore when task interleaving is considered, but two execu- tions of the same program with the same test data may not even produce the same results. Static analysis techniques are being developed for distributed systems to complement traditional testing approaches. These techniques statically determine if specific kinds of faults can occur on any ex- ecutions of the system. In this paper, we describe how the FLAVERS static analysis approach can be modified to handle the Java concurrency constructs. In addition, we present a number of patterns of use of Java’s concurrency constructs that could lead to erroneous behavior and then describe how the modified version of FLAVERS could be applied to detect these problematic or suspicious patterns. FLAVERS (FLow Analysis for VERification of Systems) uses data flow analysis techniques to verify user-specified properties of software systems . The attractiveness of this approach is in its low-order polynomial complexity bounds and its ability to improve the precision of the anal- ysis by incrementally improving the accuracy of the pro- gram model. A prototype for FLAVERS has been im- plemented, called FLAVERS/Ada, that analyzes Ada pro- grams or program models that use rendezvous communi- cations.
time verification of Javaprograms. A monitor for an Jeagle formula checks if a finite trace of program events satisfies the formula. Jeagle is a programming ori- ented extension of the rule-based powerful Eagle logic that has been shown to be capable of defining and implementing a range of finite trace monitoring logics, including future and past time temporal logic, real-time and metric temporal log- ics, interval logics, forms of quantified temporal logics, and so on. Monitoring is achieved on a state-by-state basis avoiding any need to store the input trace. Jeagle extends Eagle with constructs for capturing parameterized program events such as method calls and method returns. Parameters can be the objects that methods are called upon, arguments to methods, and return values. Jeagle allows one to refer to these in formulas. The tool performs automated program instrumentation using AspectJ. We show the transformational semantics of Jeagle.
Model checking has increasingly gained acceptance within hardware [15, 1] and protocol verification  as an additional means to discovering bugs. However, verifying programs is different from verifying hardware or protocols: the state space is often much bigger and the relationships harder to understand because of asynchronous behavior and a more complicated underlying semantics. The size and complexity of software pushes current formal verification technology beyond its limits. It is therefore likely that effective application of model checking to software verification will be a debugging process where smaller, selected parts of the software is model checked. The process will draw on multiple abstraction and verification techniques under user guidance, and is currently not well understood. In order to investigate the challenges that software poses for model checking, we have applied the Java PathFinder (Jpf) , a recently developed Java to Promela translator, in the analysis of a game server application written in Java . Promela is the modeling language of the Spin model checker . We performed the abstractions by hand and translated the simplified Java program to Promela using Jpf. Although the example is not big (16 classes and about 1400 LOC), it is still non-trivial and is not written with formal verification in mind. In the process, we developed a suspicion of a deadlock bug in the software which was confirmed using Spin. Spin also produced an even simpler error scenario than we had found ourselves.
Several other approaches to runtime verification exist, especially for Java. Java PathFinder [ 11 ] is an instrumentation of the Java Virtual Machine which is able to collect data about problematic traces and run a traditional model checking algorithm. Java PathExplorer [ 5 ] picks up the idea of runtime verifi- cation and uses the Maude rewriting logic tool [ 12 ] to implement e.g. Future or Past time LTL. Both approaches still require several components while our Haskell library is self-contained. Java PathExplorer also offers so called error pattern analysis by user-implemented algorithms. Compaq’s Visual Threads [ 7 ] debugger for POSIX threads applications allows scripted, rule-based ver- ification. The Temporal Rover [ 4 ] checks time-dependent specifications and handles assertions embedded in comments by source-to-source transformation. As future work, we intend to integrate the information from LTL checking in the graphical Concurrent Haskell Debugger to provide a comprehensive de- bugging facility for Concurrent Haskell. The effect of runtime verification on performance and memory requirements have yet to be examined for larger ex- amples. We expect to profit from the inherent sharing of sub-formulas because of our choice of a lazy functional programming language. More information on the library for LTL runtime verification can be found at
The introduction of the store buffers into the system has an important impact on the notion of independence between the operations of the system. Indeed, all memory write operations are not executed on the shared memory, but on the store buffers which are exclusively associated to a particular process. By doing so, they can be considered to be local operations with respect to independence. When considering partial-order reduction techniques, a greater set of pairs of independent transitions implies a bigger reduction of the state space, while preserving enough interleavings to correctly verify a given property (absence of deadlocks or safety properties), but removing many other interleavings leading to the same state, which only differ by the order of independent transitions. By combining cycle acceleration with partial-order reduction, we achieve a strong reduction of the state space. For programs that are correct with respect to safety properties, the size of the state space we compute is, in most cases (and of course depending on the program), not much different from the size of the state space for the same program when it is analyzed under SC with the model-checker SPIN. From an outside point of view, this might seem strange because of the addition of the store buffer components to the system and thus of more possible behaviors, but once one has understood that these buffers introduce a lot of independence, it become quite obvious why partial-order reductions work even better with the store buffers present under TSO/PSO than under SC where no store buffers are present.
We attack the problem of verifying C+MPI code using a type theory for parallel programs . Under such a framework a type describes a protocol, that is, the com- munication behaviour of a program. Programs that conform to one such type are guar- anteed to follow the protocol, and, by implication, type-safe and free from deadlocks. The type system features a dependent type language including specific constructors for some of the most common communication primitives found in the field of parallel pro- gramming, in addition to sequential composition, primitive recursion, and a form of collective choice. Dependent types are restricted to index objects drawn from the re- stricted domain of integer, floating-point values and arrays, turning type checking into a decidable problem.
method called Turchin’s supercompilation [46, 45, 44, 21] and study potential capabilities of the method for verifying the safety properties of the functional programs modeling a class of non-deterministic parameterized cache coherence protocols . We use an approach to functional modeling of non- deterministic computing systems, first presented by these authors in [29, 30, 28]. The simple idea behind the approach is as follows. Given a program modeling a deterministic computing system, whose be- havior depends on and is controlled by an input parameter value, let us call for an oracle producing the input value. Then the meta-system including both the program and the external oracle becomes non- deterministic one. And vice versa, given a non-deterministic system, one may be concerned about the behavior of the system only along one possible path of the system evaluation. In such a case, the path of interest may be given as an additional input argument of the system, forcing the system to follow along the path. Dealing with an unknown value of the additional parameter one can study any possible evolution of the system, for example, aiming at verifying some properties of the system.
Even if program verification for small programs such as smart card applets is becoming technically possible, this does not mean that it will become feasible to do it an industrial practice. Any industrial use of formal methods will have to be economically justified, by comparing the costs (the extra time and effort spent, not just for verification, but also for developing formal specifications) against the benefits (improvements in quality, number of bugs found). Here one of the benefits of JML as a specification language is that there is a range of tools that support JML that can be used to develop and check specifications. For example, the JML runtime assertion checker  tests whether programs meet specifications. This clearly provides less assurance than program verification, but requires a lot less effort, and may provide a very cost-effective way of debugging of code and formal specifications. Similarly, ESC/Java can be used to automatically check for bugs in code and annotations. We believe that having a range of tools, providing different levels of assurance at different costs, is important if one really wants to apply formal methods in practice. For an overview of the different tools for JML, see .
The combination of BON and DBC (for design), ESC/Java2 and other tools (for static checking), and RAC and the automatic generation of unit tests from specifications (for runtime checking) results in a verification-centric de- velopment process, in which verification of both behavioral specifications and program implementation occurs continu- ously throughout development. This process supports the en- tire range of development artifacts via refinement, including concepts, requirements, feature models, types, mathematical models, informally and formally annotated source code, and formally annotated object code. We have previously discussed our use of ninja techniques to teach this process to our software engineering students ; here, we present the steps of this process from the practitioner’s perspective, along with more detail about the critical tools and techniques involved. We also present process guidelines, including our code standard and our testing requirements.
relationships between objects — nor does it provide a vi- sualization of method activations in their appropriate object environments. BlueJ has no mechanism to visualize the su- perclass of an object and hence cannot clarify issues of se- mantics of method invocations in a general class hierarchy. Bloom is a software tool that allows a user to generate so- phisticated software visualizations in order to enhance soft- ware understanding . This system includes a variety of data analysis techniques, a visual query language for defin- ing what should be visualized, and a framework containing a broad range of 2D and 3D visualizations. Their goal is to let the user rapidly create a sophisticated software visualiza- tions. However, Bloom offers no mechanism for inspecting individual method activations. Its trace analysis techniques will be built upon with the dynamic analysis planned for the proposed research.
There are several approaches related to ours: Je- liot (Levy et al., 2002), Greenfoot (K¨olling, 2010), BlueJ (K¨olling et al., 2003), and JIVE (Gestwicki and Jayaraman, 2004; Lessa et al., 2010; Lessa and Ja- yaraman, 2012). Jeliot is more low-level than Cof- feeDregs, for example showing in detail how expres- sions are evaluated. This makes Jeliot very well suited to the initial stages of programming educa- tion while CoffeeDregs also seeks to support more advanced concepts. Greenfoot and BlueJ enable to, visually, interact with instances of classes, but do not aim for modeling the detailed execution of a program – Greenfoot is especially well-suited for an informal explorative introduction. JIVE is most closely com- parable to our approach. Also JIVE is much more ambitious in scope and application than CoffeeDregs: it is a dynamic analysis tool that aims to provide de- bugging facilities as well as being usable as a teach- ing tool. The lightweight approach in CoffeeDregs that restricts itself to “visualizing what happens in- side the computer”, extended to complex concepts like user interaction through the Graphical User In- terface. JIVE offers different, integrated views, for example using sequence diagrams to capture interac- tions over a longer time period. A technical differ- ence is that JIVE is integrated with the IDE Eclipse, whereas CoffeeDregs is more IDE-independent. Also the use of Visual Operational Semantics ((Jayaraman and Baltus, 1996)) and the Contour Model ((Johnston, 1971)) is subtly different. For a more detailed com- parison and full treatment of the more subtle differ- ences, see (Luijten, 2003).