A generic static analyzer for multithreaded Java programs
Software, Practice & Experience
In this paper we present ¼heckmate, the first generic static analyzer of multithreaded Java programs based on abstract interpretation. ¼heckmate can be tuned at different levels of precision and efficiency in order to prove various properties (e.g., absence of divisions by zero and data races), and it is sound for multithreaded programs. It supports all the most relevant features of Java multithreading, such as dynamic thread creation, runtime creation of monitors, and dynamic allocation of
... ry. The experimental results demonstrate that ¼heckmate is accurate, and efficient enough to analyze programs with some thousands of statements and a potentially infinite number of threads. PIETRO FERRARA The main technical features of ¼heckmate are: (i) it works at bytecode level  , so it can analyze libraries whose source code is not available, and programs written in other languages that compile to Java bytecode (such as Scala  ), (ii) it supports the main features of Java multithreading (namely, dynamic unbounded thread creation, runtime creation and management of monitors, and dynamic allocation of shared memory), and (iii) it supports many features of Java, such as strings, arrays, static fields and methods, method-calls in the presence of overloading, overriding and recursion, etc. The analysis performed by ¼heckmate is (i) whole-program, i.e., it analyzes a complete program starting from its main method; (ii) context-sensitive, e.g., it tracks information through method calls and conditional branches; (iii) completely automatic, i.e., it does not require any manual annotations, such as contracts  . We have applied ¼heckmate to several case studies and benchmarks to study its precision and efficiency. The experimental results show that ¼heckmate is (i) precise enough to catch common bugs, (ii) fast enough to be applied to programs containing thousands of statements and a potentially unbounded number of threads. The paper is structured as follows. In the rest of this section we introduce the running example used throughout this paper. Section 2 discusses related work, while Section 3 briefly sketches some background on abstract interpretation, the happens-before memory model, and its definition in a fixpoint form. Section 4 describes the architecture of ¼heckmate and discusses the main design choices and limitations. Section 5 reports and discusses the experimental results. Finally, Section 6 concludes and discusses future work. This paper is based on the work published at the 7th IEEE International Conference on Software Engineering and Formal Methods (SEFM '09)  . This section introduces some background which helps with understanding the architecture of ¼heckmate. In particular, we introduce some basic concepts about abstract interpretation, the happens-before memory model, and its fixpoint computation. Abstract Interpretation Abstract interpretation is a theory to define and soundly approximate the semantics of a program. A concrete semantics, aimed at specifying the runtime properties of interest, is defined. It is then approximated with an abstract semantics that is computable, but still precise enough to capture the property of interest. In particular, the abstract semantics must be composed of an abstract domain, an abstract transfer function, and a widening operator to make the analysis convergent if the abstract domain does not satisfy the ascending chain condition. Abstract interpretation can be applied to develop generic analyzers  . In particular, this theory allows one to define a compositional analysis, e.g., a generic analysis that can be instantiated with different numerical domains, and to analyze different properties. The Happens-Before Memory Model Memory models define which behaviors are allowed during the execution of a multithreaded program. In particular, they specify which values written in parallel may be read from the shared memory. The Java memory model  is quite complex, especially from the point of view of static analysis. Other memory models have been proposed in the past: Lamport  formalized the rule of We implemented two user interfaces: a command line tool, and an Eclipse plugin. The command line tool receives all parameters of the analysis (namely, the memory model, the numerical domain, and the property) when launching the analysis. In addition, the user has to specify the directory that contains the bytecode files to analyze, and the class containing the main method. At the end of the analysis, a list of warnings or a message stating that the program is correct are printed. The Eclipse plugin is composed of a single .jar file. In order to start the analysis, the user has to choose a class in the package explorer window, and click on "Checkmate" as shown in Figure 7 . Then a dialog will ask the user to select the property of interest (Figure 8 ). At the end of the analysis, the results are displayed in a view (Figure 9 ). In addition, the users can set the memory We applied ¼heckmate to several examples of increasing size that simulate the operations performed by a bank § . Figure 11 reports the number of abstract threads and statements of each program. Figure 12 reports the time taken by the analysis (in msec) to build up the abstraction of the § The source code of these examples can be downloaded at A GENERIC STATIC ANALYZER FOR MULTITHREADED JAVA PROGRAMS 23 50. Logozzo F, Fähndrich M. On the relative completeness of bytecode analysis versus source code analysis.