Deriving specialized program analyses for certifying component-client conformance

G. Ramalingam, Alex Warshavsky, John Field, Deepak Goyal, Mooly Sagiv
2002 Proceedings of the ACM SIGPLAN 2002 Conference on Programming language design and implementation - PLDI '02  
We are concerned with the problem of statically certifying (verifying) whether the client of a software component conforms to the component's constraints for correct usage. We show how conformance certification can be efficiently carried out in a staged fashion for certain classes of first-order safety (FOS) specifications, which can express relationship requirements among potentially unbounded collections of runtime objects. In the first stage of the certification process, we systematically
more » ... ive an abstraction that is used to model the component state during analysis of arbitrary clients. In general, the derived abstraction will utilize first-order predicates, rather than the propositions often used by model checkers. In the second stage, the generated abstraction is incorporated into a static analysis engine to produce a certifier. In the final stage, the resulting certifier is applied to a client to conservatively determine whether the client violates the component's constraints. Unlike verification approaches that analyze a specification and client code together, our technique can take advantage of computationally-intensive symbolic techniques during the abstraction generation phase, without affecting the performance of client analysis. Using as a running example the Concurrent Modification Problem (CMP), which arises when certain classes defined by the Java Collections Framework are misused, we describe several different classes of certifiers with varying time/space/precision tradeoffs. Of particular note are precise, polynomial-time, flow-and context-sensitive certifiers for certain classes of FOS specifications and client programs. Finally, we evaluate a prototype implementation of a certifier for CMP on a variety of test programs. The results of the evaluation show that our approach, though conservative, yields very few "false alarms," with acceptable performance. Abstract interpretation, model checking, software components, predicate abstraction, static analysis class Make { private Worklist worklist; public static void main (String[] args) { Make m = new Make(); m.initializeWorklist(args); m.processWorklist(); } void initializeWorklist(String[] args) { ...; worklist = new Worklist(); ... } void processWorklist() { HashSet s = worklist.unprocessedItems(); for (Iterator i = s.iterator(); i.hasNext()){ Object item = i.next(); Figure 1: An erroneous Java program fragment throwing CME. ConcurrentModificationException (or CME) when it occurs (note that the name of the exception is misleading, since it often occurs in single-threaded programs). We will use "CMP" to refer to the problem of statically determining whether a JCF client may cause CME to be thrown. Consider the Java code fragment in Fig. 1 . Here, an iterator is created on a worklist, which is implemented using a HashSet, a JCF collection class. The iterator is then used to process each item on the worklist in succession. We observe that CME can be thrown during item processing, since the nested call to doSubproblem(. . . ) causes worklist.addItem(newitem) to be called, which will in turn update the underlying HashSet while the iterator is still active. On the next iteration, the call to i.next() would cause CME to be thrown.
doi:10.1145/512537.512540 fatcat:tm3hsbj3jzfdloi63lv7n5qs64