configuring java pathfinder for concurrent java...

54
IN DEGREE PROJECT TECHNOLOGY, FIRST CYCLE, 15 CREDITS , STOCKHOLM SWEDEN 2017 Configuring Java Pathfinder for concurrent Java programs ANDREW BWOGI TUNCAY DAGDELEN KTH ROYAL INSTITUTE OF TECHNOLOGY SCHOOL OF COMPUTER SCIENCE AND COMMUNICATION

Upload: others

Post on 22-May-2020

39 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

IN DEGREE PROJECT TECHNOLOGY,FIRST CYCLE, 15 CREDITS

, STOCKHOLM SWEDEN 2017

Configuring Java Pathfinder for concurrent Java programs

ANDREW BWOGI

TUNCAY DAGDELEN

KTH ROYAL INSTITUTE OF TECHNOLOGYSCHOOL OF COMPUTER SCIENCE AND COMMUNICATION

Page 2: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

Configuring Java Pathfinderfor concurrent Java programs

ANDREW BWOGI AND TUNCAY DAGDELEN

Degree Project in Computer ScienceDate: June 5, 2017Supervisor: Dilian GurovExaminer: Örjan EkebergSwedish title: Konfigurering av Java Pathfinder för Javaprogrammed samtidiga processerSchool of Computer Science and Communication

Page 3: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

iii

Abstract

Software verification is a field of computer science dedicated to guar-antee that a program runs according to a formalized specification. Ofvarious kinds of verification techniques model checking tries all possi-ble states of a program and makes sure each state satisfies a set of for-malized properties. Java Pathfinder (JPF) is a tool that automaticallymodel checks Java bytecode. This report studies general configurationpatterns for JPF that leads it to either terminate without errors or ter-minate with found concurrency bugs for different types of programs.The types considered are solutions to producer-consumer problems,barber shop problems, reader-writer problems and programs fallingunder the type server-client systems. The main part of the method isfirst a search for these types of programs using cloud-based revisioncontrol systems. Second, these programs are verified with the helpof the JPF documentation, articles on the subject and online discus-sion groups. The results are configurations that lead to no errors, con-currency bugs and native method errors depending on the programverified. An important limitation of the report is the absence of largeprograms that challenge JPF’s state space handling. The resulting gen-eral configuration patterns found are applicable to small programs notusing native methods. A pattern is also found for programs with na-tive methods, but here it is possible that the user must modify a modelclass in JPF.

Page 4: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

iv

Sammanfattning

Programverifikation är ett datalogiskt fält som säkerställer att pro-gram fungerar enligt en formaliserad specifikation. Modellkontroll ärett delområde i programverifikation som testar alla möjliga tillstånd iett program för att se om de uppfyller en mängd formaliserade egen-skaper. Java Pathfinder (JPF) är ett verktyg som automatiskt kontrolle-rar bytekod i Java. Syftet med den här rapporten är att undersöka vil-ka generella konfigurationsmönster som finns för särskilda program-typer som leder till att JPF antingen terminerar utan fel eller med ettfunnet samverkningsfel. Programtyperna som undersöks är lösningartill producer/consumer-problem, barber shop-problem, reader/wri-ter-problem och program som faller under typen server/klient-pro-gram. Metoden består i huvudsak först av sökning efter program imolnbaserade versionshanteringssystem. Sedan följer programkontrollmed hjälp av JPF-dokumentation, artiklar om ämnet och diskussions-grupper online. Resultatet är ett antal konfigurationer som leder tillinga fel, fel på grund av samtidig trådkörning och fel på grund av di-rekt körbar kod, beroende på det verifierade programmet. En viktigbegränsning med rapporten är frånvaron av stora program som tes-tar JPFs hantering av stora tillståndsrymder. De funna generella kon-figurationerna är tillämpbara på små program som inte använder di-rekt körbar kod. En generell konfiguration hittades även för programsom använder direkt körbar kod, men här måste användaren eventu-ellt skriva om en modellklass i JPF.

Page 5: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

Contents

1 Introduction 11.1 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . 41.2 Problem statement . . . . . . . . . . . . . . . . . . . . . . 51.3 Scope of study . . . . . . . . . . . . . . . . . . . . . . . . . 51.4 Approach . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61.5 Report disposition . . . . . . . . . . . . . . . . . . . . . . . 6

2 Background 72.1 Concurrency . . . . . . . . . . . . . . . . . . . . . . . . . . 72.2 Concurrency in imperative and functional languages . . 72.3 State of the art . . . . . . . . . . . . . . . . . . . . . . . . . 8

2.3.1 Message passing . . . . . . . . . . . . . . . . . . . 82.3.2 Threaded programming . . . . . . . . . . . . . . . 9

2.4 Concurrency bugs . . . . . . . . . . . . . . . . . . . . . . . 92.4.1 Atomicity violation . . . . . . . . . . . . . . . . . . 102.4.2 Order violation bugs . . . . . . . . . . . . . . . . . 102.4.3 Deadlocks . . . . . . . . . . . . . . . . . . . . . . . 112.4.4 Races . . . . . . . . . . . . . . . . . . . . . . . . . . 12

2.5 Different types of concurrent programs . . . . . . . . . . 122.5.1 Producer-consumer . . . . . . . . . . . . . . . . . . 122.5.2 Barber shop . . . . . . . . . . . . . . . . . . . . . . 132.5.3 Reader-writer . . . . . . . . . . . . . . . . . . . . . 132.5.4 Server-client programs . . . . . . . . . . . . . . . . 13

2.6 Multithreading with the Java programming language . . 142.6.1 The Java platform . . . . . . . . . . . . . . . . . . . 142.6.2 Wait/notify . . . . . . . . . . . . . . . . . . . . . . 14

2.7 Software verification and model checking . . . . . . . . . 152.7.1 Verification of concurrent programs . . . . . . . . 152.7.2 Model checking theory and software testing . . . 17

v

Page 6: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

vi CONTENTS

2.8 Java Pathfinder . . . . . . . . . . . . . . . . . . . . . . . . 192.8.1 State space reduction . . . . . . . . . . . . . . . . . 192.8.2 State storage . . . . . . . . . . . . . . . . . . . . . . 202.8.3 Error detection . . . . . . . . . . . . . . . . . . . . 202.8.4 JPF extensions . . . . . . . . . . . . . . . . . . . . . 20

2.9 JPF Configuration . . . . . . . . . . . . . . . . . . . . . . . 21

3 Method 243.1 General remarks . . . . . . . . . . . . . . . . . . . . . . . . 243.2 Software discovery . . . . . . . . . . . . . . . . . . . . . . 243.3 Configuring and running JPF . . . . . . . . . . . . . . . . 253.4 JPF outcomes . . . . . . . . . . . . . . . . . . . . . . . . . 253.5 Generalization . . . . . . . . . . . . . . . . . . . . . . . . . 26

4 Results 274.1 Common configuration properties . . . . . . . . . . . . . 27

4.1.1 Site properties . . . . . . . . . . . . . . . . . . . . . 274.1.2 Project properties . . . . . . . . . . . . . . . . . . . 284.1.3 Application properties . . . . . . . . . . . . . . . . 284.1.4 JPF Statistics . . . . . . . . . . . . . . . . . . . . . . 28

4.2 Specific configuration properties . . . . . . . . . . . . . . 294.2.1 UDP-File-System-Query-Framework . . . . . . . 294.2.2 Producer-consumer-instance-1 . . . . . . . . . . . 314.2.3 Reader-writer-instance-1 . . . . . . . . . . . . . . . 324.2.4 Barber-shop-instance-1 . . . . . . . . . . . . . . . . 334.2.5 Restaurant simulator . . . . . . . . . . . . . . . . . 34

5 Discussion 375.1 Analysis of results . . . . . . . . . . . . . . . . . . . . . . . 37

5.1.1 Programs with native methods . . . . . . . . . . . 375.1.2 Programs without native methods . . . . . . . . . 385.1.3 General results . . . . . . . . . . . . . . . . . . . . 39

5.2 Limitations and critique . . . . . . . . . . . . . . . . . . . 405.2.1 Method critique . . . . . . . . . . . . . . . . . . . . 405.2.2 Extensions . . . . . . . . . . . . . . . . . . . . . . . 415.2.3 Usability and documentation . . . . . . . . . . . . 41

6 Conclusion 43

Bibliography 46

Page 7: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

Chapter 1

Introduction

In this part, the subject will be introduced in general and related tosociety and economy. First comes an explanation of the subject andthen its aspects, which is verification, concurrency and model check-ing software. Then, the motivation behind the report is explained, fol-lowed by the problem statement, its scope, approach and the generaldisposition of the report.

In 1998 a research team set out to formally analyze a spacecraft con-trol system driven by artificial-intelligence algorithms at NASA. Theyrepresented the system in a formal language and ran the translationthrough a verification program. Previously undiscovered concurrencybugs were found [10]. This case shows how disasters can be preventedby analyzing code before it is deployed. A vision of computer sci-entists that work with program verification is to create a verificationprogram capable of taking in an entire software program and auto-matically analyzing it to find all existing bugs. It is however far fromreality. This report investigates an area of such software verification.

The report studies general configuration patterns for program ver-ification with the tool Java Pathfinder (JPF). Programs verified are con-current Java programs using only the functions wait() and notify()for synchronization. The JPF is distributed in a highly modular way.This makes it flexible but at the same time difficult to set up at the ini-tial phase of verification. The report aims to speed up set up time bydescribing general configuration patterns depending on types of Javaprograms with the above specified restrictions. The program typesare based on traditional problems studied in concurrency theory anddifferences in program functionality. This is elaborated in the back-

1

Page 8: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

2 CHAPTER 1. INTRODUCTION

ground section.Software verification is a discipline of software engineering that

analytically studies the correctness of programs. This means to ensurethat programs run as they are expected according to prespecified for-mal properties. The discipline is especially important in areas wheresafety is of great concern, for instance in transportation and nuclearpower control systems.

JPF is a specific kind of software verification tool. It is a modelchecker. The first version of it was developed in 1999 at NASA by theRobust Software Engineering group. This group is still the principalmaintainer of the program but other parties, both commercial and aca-demic, are involved in the project [18]. As a model checker, JPF triesall possible inputs to a program as well as simulating operating systemfunctionality like context switching. It does so in order to determineif a concurrent program runs without races, deadlocks and exceptionsin all possible states that it can exist in.

Figure 1.1 shows a simplistic overview of how JPF works. It takesa Java program and its corresponding configuration file. The config-uration file tells JPF specifically what settings JPF should take in con-sideration when running the program.

Figure 1.1: Overiew of the JPF

To show an example, figure 1.2 shows the source code of a Javaprogram called Racer. This program is intentionally written so that itcontains a race bug. The task of the JPF is to find this bug. The figure1.3 below shows the configuration file of the Racer program. It tellsthe JPF to specifically look for races. The JPF then checks the Racerprogram according to the settings specified by the configuration file.The output of the JPF is shown in figure 1.4.

Page 9: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

CHAPTER 1. INTRODUCTION 3

Figure 1.2: The source code of the Racer program

Figure 1.3: The configuration file of the Racer program

Page 10: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

4 CHAPTER 1. INTRODUCTION

Figure 1.4: The output of JPF after running the Racer program and itsconfiguration file

1.1 Motivation

Safe systems are a requirement for end consumers. This is becausesafety is implied in the proper working of a system which the con-sumer expects since he or she uses it as a means to achieve a particularend. For instance, a consumer expects that a bank transaction sys-tem delivers money sent from one destination to another arrives at theright place and in the same state as it is sent. A safe bank transactionsystem therefore guarantees this property to hold for every transac-tion among other consumer expectancies. For the producer, systemsthat are verified early in the production stage lead to shorter devel-opment cycles with less debugging and software updates which are

Page 11: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

CHAPTER 1. INTRODUCTION 5

costly.The motivation behind this work is to see the usefulness of JPF for

software engineers working with concurrent programs. If so, softwareverification could be a useful complement to traditional testing in or-der to create as bug free programs as possible.

As usefulness, the report aims specifically to address the set uprequirements for the JPF in verifying different types of programs. Theuser should be able to look up general configuration patterns for thetype of program he or she is using. The concluding work is thus meantto alleviate the difficult configuration patterns in JPF and lead to fasterstart up times for using it. From this perspective, the report also aimsto improve the JPF documentation.

1.2 Problem statement

The problem we are considering is, given Java programs that only syn-chronize with functions wait() and notify(), what general config-uration patterns are there that enables JPF to decide whether a pro-gram contains concurrency bugs or not? Are there any patterns thatare specific for different types of concurrent programs?

The types considered are solutions to producer-consumer prob-lems, barber shop problems, reader-writer problems and programsfalling under the type server-client systems.

1.3 Scope of study

The configuration of JPF will be limited to its three main configurationlayers: site, project and application properties. The properties config-ured include strategies for curbing the state explosion problem, by-passing native methods and handling program specific features suchas network interfaces. By general patterns of configuration we mean(1) a set of features common to all specific instances of configurationfor Java programs with wait() and notify() that leads to JPF de-ciding if there are concurrency bugs or not and (2) a set of featurescommon to a specific type of Java concurrent program with wait()and notify(). Only Java programs will be studied and they areall multi-threaded, concurrent and only use wait() and notify()for synchronization. It must be stated that the use of wait() and

Page 12: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

6 CHAPTER 1. INTRODUCTION

notify() is not the predominant way of synchronizing. There areother synchronization mechanism such as locks.

The JPF can also be configured by rewriting the source of the coredistribution or any of its extensions, or by adding custom classes. Thesetechniques will not be employed in this study. The study is limitedto using scripts to activate and deactivate functions that are alreadyavailable in the core distribution or an extension.

If the programs studied are modified, they will be done so only bychanging loop parameters to exemplify the extent to which a configu-ration can handle a certain state space. The basic functionality of theprogram will in all cases remain the same.

1.4 Approach

In order to find programs that fulfill the criteria in the scope of study,the development platforms GitHub and Bitbucket have been used.Configurations have been found in the JPF documentation and arti-cles.

1.5 Report disposition

The background goes through the most important concepts in orderto understand the method and the results. These include concurrencybugs, the Java platform and constituent parts of the JPF. The methodsection explains the preparation for the study, the verification processand result analysis. Last, the results are presented, discussed and aconclusion is formed.

Page 13: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

Chapter 2

Background

In this section concepts important to understand the methods and re-sults in this study will be presented. There is an overview of concur-rency bugs in general followed by an introduction to synchronizationtechniques in the Java language using wait() and notify(). Afterthis comes a presentation of program verification and the core func-tionality of the Java Pathfinder together with its different extensions.

2.1 Concurrency

In a concurrent program, the program is divided into several partswhich can be executed simultaneously. By doing so, a program candisplay novel functionality such as multiple user interaction and insome cases the performance of the program increases. However, thedifferent parts of the program must be executed in a synchronizedfashion. Otherwise unwanted behavior may appear during the exe-cution of the program.

2.2 Concurrency in imperative and functionallanguages

In imperative languages, like Java or C++, the programmer specifiesstep-by-step changes to variables and data structures. Control con-structs (e.g., for loops), low-level data manipulations, and shared mu-table object instances make programs in these languages difficult toanalyze regarding the issue of concurrency.

7

Page 14: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

8 CHAPTER 2. BACKGROUND

The common belief is that functional languages, such as Schemeor Haskell, could eliminate this difficulty because they are naturallysuited to concurrency. Programs written in these languages manipu-late immutable object instances, which pose no concurrency hazards.Moreover, without side effects, programs seem to have fewer con-straints on execution order.

In practice, however, purely functional languages are not necessar-ily conducive to concurrency. Most functional languages allow someside effects to mutable state, and code that uses these features is dif-ficult to parallelize automatically. The real contribution of functionallanguages to concurrency comes in the higher-level programming stylecommonly employed in these languages, in which operations such asmap or map-reduce apply computations to all elements of an aggre-gate data structure [20].

2.3 State of the art

Regarding concurrency, there are two state of the art mechanism to im-plement synchronization: explicit message passing and threaded program-ming. Threaded programming is a dominant model for realizing con-currency within application logic for general purpose programs suchas games or business applications. Message passing on the other handdominates the world of large scale parallel computing for scientificsimulation where shared memory may not exist in the context of largeprocessor-count hardware platforms. Message passing is also used toimplement many distributed systems that are commonplace on the In-ternet [16].

2.3.1 Message passing

One of the oldest models of concurrent programming that traces itsroots to C.A.R. Hoare is the model of communicating sequential pro-cesses, or CSP. The premise of Hoare’s model is that processes aretreated as independent entities, with their own state and program counterthat is not accessible to other processes. Interactions required to coor-dinate execution or share data are explicitly stated via messages thatare passed between the processes [16].

A language that uses message passing is for example Erlang. Mes-sages between Erlang processes can be lists, tuples, integers and so on.

Page 15: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

CHAPTER 2. BACKGROUND 9

Each process has its own input queue for messages it receives. Newmessages received are put at the end of the queue. When a processexecutes a receive, the first message in the queue is matched againstthe first pattern in the receive. If this matches, the message is removedfrom the queue and the actions corresponding to the pattern are exe-cuted [8].

2.3.2 Threaded programming

In a single-threaded program, the instructions of the program will befetched and executed from a single program counter. Effectively, thismeans that the program is executed sequentially where one task mustbe finished before the next task can begin.

In a multi-threaded program, there exists more than one programcounter where instructions will be fetched and executed from. Thisenables the CPU to execute different parts of the program concurrently.That is, one task does not have to wait for another task to finish. In thisway, a program may for example run faster than if it was executed ona single thread.

However, running multiple threads in a program can cause unde-sirable effects, namely concurrency bugs, which are described below[1].

2.4 Concurrency bugs

A comprehensive study by Shan Lu has examined concurrency bugpatterns from the following four applications: MySQL (a popular databasemanagement system), Apache (a well-known web server), Mozilla (afamous web browser) and OpenOffice (a free version of the MS Officesuite).

Lu’s study divides concurrency bugs into two classes: non-deadlockbugs and deadlock bugs. There is also a bug named data race whichLu’s study defines in a separate class.

The study shows that 70 percent of the bugs that appeared werenon-deadlock bugs and 30 percent were deadlock bugs. Understand-ing these results can help understanding what types of problems actu-ally occur in mature code bases.

There are two major types of non-deadlock bugs: atomicity viola-tion and order violation [15].

Page 16: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

10 CHAPTER 2. BACKGROUND

2.4.1 Atomicity violation

Lu defines atomicity violation as “the desired serializability among mul-tiple memory accesses is violated (i.e. a code region is intended to be atomic,but the atomicity is not enforced during execution).”

Two different threads access the field proc_info in the examplebelow. Thread 1 checks if the field is non-NULL and then prints itsvalue. However, thread 2 can set the field to NULL, after thread 1has checked it in the if() statement but before the print statementfputs(). Thus when thread 1 resumes, it will crash, as a NULLpointer will be dereferenced in the print statement [1].

1 Thread 1 : :2 i f ( thd−>proc_info ) {3 . . .4 fputs ( thd−>proc_info ) , . . . ) ;5 . . .6 }78 Thread 2 : :9 thd−>proc_info = NULL;

Listing 2.1: Atomicity violation

2.4.2 Order violation bugs

Order-violation is defined by Lu as “the desired order between two (groupsof) memory accesses is flipped (i.e., A should always be executed before B, butthe order is not enforced during execution)".

In the example below, the code in thread 2 assumes that the vari-able mThread has already been initialized. However, if thread 2 runsimmediately once created, the value of mThread will not be set whenit is accessed within mMain() in thread 2, and will likely crash with aNULL-pointer dereference [1].

1 Thread 1 : :2 void i n i t ( ) {3 . . .4 mThread = PR_CreateThread (mMain , . . . ) ;

Page 17: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

CHAPTER 2. BACKGROUND 11

5 . . .6 }78 Thread 2 : :9 void mMain ( . . . ) {

10 . . .11 mState = mThread−>S t a t e ;12 . . .13 }

Listing 2.2: Order Violation

2.4.3 Deadlocks

Deadlock occurs if and only if the following four conditions are satis-fied:

• Mutual exclusion: Only one thread can use the resource (e.g. alock).

• Hold-and-wait: A thread is currently holding at least one re-source (e.g. lock that they already acquired) and requesting ad-ditional resources (e.g. locks) which are being held by otherthreads.

• No preemption: A resource (e.g. lock) can be released only bythe thread holding it

• Circular wait: Each thread is waiting for a resource (e.g. lock)which is being held by another thread, which in turn is waitingfor the first thread to release the resource [1].

Page 18: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

12 CHAPTER 2. BACKGROUND

Figure 2.1: The figure illustrates a scenario where all of the four condi-tions are met.

2.4.4 Races

A data race exists when multiple threads concurrently read and writethe same data, and the outcome of the execution depends on the par-ticular order in which the accesses take place. The threads must syn-chronize to avoid race conditions.

2.5 Different types of concurrent programs

The types of programs below represents typical uses of concurrency.They can be parts of larger systems but here they are considered inisolation. The distinguished types are based on traditional problemsstudied in concurrency theory as well as differences in functionalityelaborated under each respective heading.

2.5.1 Producer-consumer

The problem consists of two processes, the producer and the consumer,who share a common buffer used as a queue. The producers job is togenerate data, put it into the buffer, and then restart this process. Atthe same time the consumer is removing data from the buffer. Theproblem is to make sure that the producer does not add data into thebuffer if it’s full and that the consumer does not remove data from anempty buffer [1].

Page 19: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

CHAPTER 2. BACKGROUND 13

2.5.2 Barber shop

The barber shop has two rooms - a waiting room with a limited num-ber of places and a treatment room with a single chair. First, drop-incustomers get into the waiting room. If there is any free waiting place,a customer takes a place in the queue. Otherwise, the customer leavesthe barber shop. If there are any customers in the waiting room, a bar-ber asks the first one in the queue to proceed into the treatment room.Then the barber makes the customer a haircut. After the treatmentis completed, the customer leaves the barber shop and the barber callsthe next customer (if there is any waiting). Otherwise, the barber waitsfor new drop-in customers [13].

2.5.3 Reader-writer

The problem is that there exists two groups of threads which sharecommon storage. In one of them, readers read stored data, being ableto neither delete nor edit it. In the other, writers add data into the stor-age. Certain restrictions apply in this case: (1) multiple writers cannotoperate simultaneously, (2) read operations are not possible while newdata is being entered into the storage and (3) multiple readers can op-erate simultaneously [13].

2.5.4 Server-client programs

Server-client programs are characterized by separate programs com-municating with one another in a network through a protocol. In par-ticular one program (the server) is distinguished by the others (theclients) in that it itself is connected to the clients without the clientsnecessarily being connected between themselves. There are severaldifferent ways to implement this program type but a common one hasthe clients connecting to a server port, while the server is listening topossible connecting clients through a socket. Once a connection is es-tablished, the client requests a particular function from the server thatreceives the request, treats it and sends the requested data back to therequesting client.

Page 20: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

14 CHAPTER 2. BACKGROUND

2.6 Multithreading with the Java programminglanguage

2.6.1 The Java platform

The Java platform consists of the Java application programming inter-faces (APIs) and the Java virtual Machine (JVM). Java APIs are librariesof compiled code that can be used in programs. These programs canthen be interpreted by the JVM. Rather than running directly on thenative operating system, the Java program is interpreted by the JVMfor the native operating system.

The Java language supports writing programs with multiple threads.There exists different strategies to synchronize threads of which one isusing two methods, wait() and notify() to synchronize multiplethreads.

2.6.2 Wait/notify

By invoking wait() the current thread gets suspended, which meansthat the code that follows wait() will not be executed. In order forthis thread to continue its execution, another thread must invoke thenotify() method.

In the brief example below, thread 1 executes the produce()methodand thread 2 executes the consume() method.

1 public void produce ( ) throws InterruptedExcept ion {2 synchronized ( t h i s ) {3 . . .4 wait ( ) ;5 foo1 ( ) ;6 }7 }8 }

Listing 2.3: Thread 1 executes the produce() method

Thread 1 gets suspended because the wait() method is invoked.Therefore foo1() will not be executed until another thread invokesnotify():

Page 21: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

CHAPTER 2. BACKGROUND 15

1 public void consume ( ) throws InterruptedExcept ion {2 synchronized ( t h i s ) {3 . . .4 n o t i f y ( ) ;5 foo2 ( ) ;6 }7 }

Listing 2.4: Thread 2 executes the consume() method

Thread 2 invokes notify(). However, in order for thread 1 tocontinue its execution thread 2 must also execute the code in the restof the block, in this case foo2(). Now, thread 1 will continue its exe-cution by invoking foo1().

2.7 Software verification and model check-ing

Software verification has its historical roots in a logic created by Hoarein the late 60s now called Hoare-logic. The idea was to derive the de-sired end state of a program from initial assumptions or inputs to aprogram through a line by line formally valid derivation of values asthey passed through program functions [11]. This was initially a man-ual technique but not long after the invention of Hoare-logic, auto-matic theorem provers were developed. One early automatic theoremprover was LCF from 1972 that proved programs written in the formallanguage ML [17].

Since then theory, techniques and tools for software verificationhave developed in a number of directions for different purposes. Herefollow some modern software verification techniques for concurrentprograms in general and Java in particular. After that comes an expla-nation of model checking which is the software verification techniqueused in JPF.

2.7.1 Verification of concurrent programs

Verification of concurrent programs is a difficult problem due to themany different states in which a multiple threaded program can exist.Every sequence of interruptions from the operating system that causes

Page 22: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

16 CHAPTER 2. BACKGROUND

a different thread to run is one program path. Since interruptions hap-pen at a high speed, the number of possible thread interleavings be-comes vast and unmanageable manually. Techniques of concurrentprogram verification therefore include abstracting away parts of theprogram that has no bearing on possible concurrency bugs as well asautomating a large part or everything of the verification process. Hereare two examples of how verification of concurrent programs works.

Leino, Müller, and Smans [14] show that deadlocks can be pre-vented by enforcing two rules when a program is using a combina-tion of channels and locks. Channels refer to the messaging system inCSP discussed in section 2.3.1. The first rule states that a thread canonly be blocked if another thread holds an obligation to send a noti-fication through their common channel. The second rule states thateach thread must acquire locks and receive notifications according toa specific order. The authors then go on to implement this techniquein the programming language and verifier Chalice.

De Carvalho Gomes, Gurov, and Huisman [6] have studied the useof conversion from one programming language to another in order toverify concurrent programs using condition variables. Their approachis based on annotating Java programs according to a scheme the au-thors specify, and using the annotation to extract a corresponding pro-gram in the language SyncTask. They go on to prove that the Javaprogram is correctly synchronized if and only if the correspondingSyncTask program terminates. They prove it by another transforma-tion, this time from a SyncTask program to hierarchical Colored PetriNets (CPN) and solving the reachability problem of the latter struc-ture. They use the STAVE tool for extracting the SyncTask program aswell as the CPN, and CPN tools like PIPE for analysis.

These examples show different ways to verify concurrent programs.One advantage of the first example is the abstraction from irrelevantfeatures of a program that makes verification faster. The second hasthe advantage of being applicable to programs with both locks andchannels. Both techniques have the weakness of requiring manual la-bor to annotate and code the tested program into another language.Besides these there are many other techniques that each has its ownstrengths and weaknesses. Next the technique model checking is ex-plored, which differs from the above examples.

Page 23: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

CHAPTER 2. BACKGROUND 17

2.7.2 Model checking theory and software testing

Model checking emerged in the early 80s from the work of Clarke andEmerson, and independently from Quielle and Sifakis [5]. It can bestated in a succinct form: If M is a state-transition graph (a so calledKripke structure) and f is a formula of temporal logic, does M, s en-tail f for all states s of M [4]? A state is represented by an evaluationof the program counter which includes information about the valuesof all program variables and the configurations of the stack and heap.A transition formalizes the evolution from one state to another. Theformula f written in temporal logic represents a property of the pro-gram supposed to hold in every possible state. Such properties can bedivided into safety and liveness properties. The former excludes badstates such as assertion violation and NULL pointer dereference. Thelatter represents that the program eventually gets to a desired statesuch as termination or lock release [7]. Put in a different way, modelchecking tries all different possible program paths, and thus ensuresthat the program is correct in every possible state it can exist in.

This can be contrasted to software testing which only tries one par-ticular program path at a time. To manually test all possible stateswould be a tedious work so testing is often limited to boundary casesand typical scenarios. These program paths can miss subtle problem-atic states of a program that lead to errors. The difference is shownin figures 2.2 and 2.3. The double advantage of model checking com-pared with testing is in other words automation and exhaustiveness.Another important advantage is that if an error does occur, there isa counter example that the specification does not hold and it can bederived from the states and transitions leading to it. This produces aprogram trace that can be used in debugging [4].

Not long after model checking as a theory was developed, toolsfor model checking were developed. An early such tool was the ECMsystem [4]. Model checking tools usually verify programs written inspecialized formal languages. A modern example of this is the SPINsystem [12]. The strength of JPF is that it verifies programs written ina mainstream programming language and does not need to convertprograms to a different formal language [21].

Page 24: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

18 CHAPTER 2. BACKGROUND

Figure 2.2: Testing: based on input set {d} only one path is executed ata time.

Figure 2.3: Model Checking: all program states are explored until noneare left or a defect is found.

Page 25: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

CHAPTER 2. BACKGROUND 19

2.8 Java Pathfinder

The first version of the JPF converted Java source code to a specializedformal language, PROMELA, also used by the model checker SPIN.The second version, the version used in this study, works directly onJava bytecode. One of the main reasons for this switch is that a largerportion of programs can now be verified because program librariesmost often exist as bytecode and since their source code is lacking,can’t be converted to a formal language. JPF thus implements its ownvirtual machine. It is completely written in Java which means that theJPF VM runs on the JVM.

2.8.1 State space reduction

In order for JPF to perform in reasonable time, it has to solve the prob-lem that a program might be able to exist in too many, possibly infinitenumber of states. It employs several techniques to curb this so calledstate space explosion.

Symmetry reduction is based on equivalence classes for states so thatstates can be discarded if they resemble close enough already visitedstates. Abstraction replaces parts of the data in the code with abstractvariables. This is for abstracting subcomponents of a program that istoo complicated to apply abstraction globally. This step is done in thesource code and is a manual process [3].

Static analysis comprises a number of different techniques that treatsa program without executing it and disregarding its input, making theanalysis valid for every input. JPF uses for its purposes of reducingstate space three techniques: static slicing and partial evaluation thatboth generate a functionally equivalent smaller program than the orig-inal one, and partial order computation that identifies statements thatcan be run concurrently with any other statement without any pro-gram failures.

Finally run time analysis extracts from a once executed programpath a number of properties of other possible paths. Even if no er-ror has been found in the executed path, the extracted information canshow errors in potential paths [21].

Page 26: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

20 CHAPTER 2. BACKGROUND

2.8.2 State storage

Another obstacle for JPF to perform in reasonable time is the problemthat states can be revisited. A technique to solve the so called complexstate problem makes use of the way a state is represented in a datastructure. This means that a path that has been traced once does nothave to be traced again if its representation can be found in a datastructure. In short, a state is represented through a collapse functionthat codes the important parts of the state in an integer vector [21].

2.8.3 Error detection

The algorithms in JPF for data race and deadlock detection falls underthe category of run time analysis. It is therefore not necessary to actu-ally execute all possible program paths to find all potential deadlockand race bugs. It is only necessary to execute enough program states toextract information to cover the remaining states. The two algorithmsare Eraser for race detection and Lock-Tree for deadlock detection.

Eraser uses a state machine to code a current state of a lock. De-pending on if threads read or write to a particular lock protected vari-able, the variable enters different states that represent whether poten-tial races are possible or not. If a thread writes to a variable that existsin a critical state, JPF issues an error.

The Lock-Tree algorithm uses a tree data structure to save in whatorder a thread grabs its locks. When the program terminates the treesfor the various threads are compared and deadlocks can be detected.

If JPF encounters an error the trace of the program states leadingto it is presented in the terminal. The visualization of the error tracecomes from an independent tool package for model checking calledBANDERA, which was partially integrated into the JPF [21].

2.8.4 JPF extensions

The description of JPF above covers the core or basic package. TheJPF was created in a modular fashion so besides the core numerousextensions can be added to the system. Below extensions that are usedin this report are described.

Page 27: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

CHAPTER 2. BACKGROUND 21

JPF-nhandler

For the purposes of this study one particular extension will be impor-tant, the JPF-nhandler. Its function is to delegate native method callsin Java libraries from the JPF virtual machine to the underlying JVM.Native method calls pose a problem to JPF because they are made out-side the Java platform and because of this are not traceable by the JPFvirtual machine. JPF solves this in some cases by creating its own mod-els of the native methods which are called instead of the original ones.Not all native methods are however modeled in this way. For this rea-son, the extension jpf-nhandler was created to allow the user to choosewhat functions should be passed to the JVM [19].

JPF-racefinder

The JPF-racefinder (JRF) is a precise data race detectable extension toJPF. The motivation for JRF comes from the unsound nature of JPF ina Java memory model that is relaxed and does not require sequentialconsistency for performance reason. The main contribution of JRF isthat the absence of data races verified by JRF guarantees the soundnessof a succeeding proof using JPF [9].

JPF-net-iocache

The extension JPF-net-iocache is used for distributed programs. Itmodel checks one program in a distributed system while other pro-grams run normally on the JVM simultaneously. The main function ofit is to simplify the backtracking mechanism for distributed programs.Instead of programs exchanging actual data at every interleaving, partof this process is coded in a cache thus speeding up the verification.Further, a number of Java classes for use in networks are modeled init, making external delegation unnecessary [2].

2.9 JPF Configuration

The JPF is configured through three property types each representedby a configuration file. The files are placed in specific folders outlinedin the JPF manual and have the file extension .properties except the ap-plication properties which have the extension .jpf. The property typesare hierarchical layers that determine how JPF is run and what parts

Page 28: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

22 CHAPTER 2. BACKGROUND

of it is used. In the top most layer, the site properties, the different JPFextensions are connected and the location of the JPF is chosen. Rightunderneath this is the project properties which contains all preferencesspecific to a particular extension. The most important entries here areclasspath and sourcepath locations that refer to the locations of classesof the JPF itself, the system under test and the sources of the systemunder test. A system under test (SUT) is the program that is modelchecked. The bottom layer is the application properties that determinehow a system under test should be run. Here various preferencesfrom the different extensions are set up and the kinds of bugs that JPFshould look for is chosen [18]. Last, there are command line propertiesused for debugging. These will not be used in this study. The pro-cess of initialization is passed through these four layers and producetogether a configuration object which is made up of string values. Theprocess is visualized in figure 2.4.

Page 29: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

CHAPTER 2. BACKGROUND 23

Figure 2.4: The formation of the JPF configuration object

Page 30: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

Chapter 3

Method

What follows is first a general idea of the intended results and thepath leading there. Then comes a more specific description of the stepstaken after the problem has been formulated to the production of theresults. Last there is a formulation of the criteria looked for accordingto the problem statement and the method for generalizing the results.

3.1 General remarks

The aim of this study is to produce configuration properties to be useddepending on the type of program being considered. In general, soft-ware were found and run through the JPF with different configura-tions until a desired outcome was achieved. If an outcome for a pro-gram could not be reached according to desired requirements, the ac-tually reached outcome was recorded. The sum of recorded resultswere then put together and analysed to produce general configura-tions valid for a class of program types or for a specific program type.

3.2 Software discovery

One main part of this thesis is to find programs that can be checkedby the JPF. The JPF can only handle programs written in Java, there-fore the search focuses only on Java programs. A further restrictionimposed on the search is that the chosen program must contain theJava methods wait() and notify(). In order to find programs thatfulfills these criteria, the development platform GitHub and Bitbucket

24

Page 31: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

CHAPTER 3. METHOD 25

has been used. These platforms provide advanced search functionsthat makes it easier to find specific kind of programs. Also, severalprograms were provided by Cyrille Artho at KTH Royal Institute ofTechnology. The different program types were found by reading theprogram documentation, and comparing the program’s functionalitywith the suggested program types.

3.3 Configuring and running JPF

Configuration properties where looked for in the example programsshipped with JPF, the JPF documentation, in articles explaining the JPFand its extensions. Besides literature research, the Google group JavaTM

Pathfinder was used in order to get detailed information about the JPFand the extensions that works with JPF. This group was of significancebecause developers of the different JPF extensions contribute to theforum. Extensions were selected according to its features from a list ofextensions found in the JPF documentation.

3.4 JPF outcomes

There are two goals that are used to signify a desired JPF outcome andtherefore from the perspective of this report a successful verificationof the SUT. The first goal is that JPF terminates without errors. HereJPF itself prints that no errors were found. The other goal is that JPFterminates with a concurrency bug. By a concurrency bug is meanteither a race or a deadlock. Here JPF prints that an error was foundwith a description of the error.

However, other possible JPF terminations are possible where it printsan error, for instance that an exception in the program was thrown dueto a NULL pointer dereference. Although this kind of error is not aconcurrency bug, it is still interesting as it exemplifies JPF’s capabil-ity for program testing. These results will not be given any weight inanalysis but simply recorded since they are a result of faulty programsfor other reason than the difficulty of writing concurrent programs.

JPF can also terminate due to a native method error. This is thekind of termination that this report is supposed to solve, to transformit to one of the errors mentioned above. A different possibility is thatJPF does not terminate at all but keeps checking states in a state space

Page 32: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

26 CHAPTER 3. METHOD

explosion. This situation is also one of the main obstacles this reportaims to solve by proper JPF configurations.

3.5 Generalization

After the discovery of a number of configuration files for the differentconfiguration layers, a process of generalization begins to find generalconfiguration patterns. Configuration files are collected and sortedaccording to what configuration layer and program type they belongto. Common configuration properties for each such category are thenlooked for, extracted and put into the resulting general configurationpattern.

Page 33: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

Chapter 4

Results

In this section results are presented of how JPF was configured forvarious programs. The section is divided in two parts. The first partoutlines properties that are common in all configuration files. The sec-ond part covers the configuration for specific programs and explainsproperties that are specific to the programs.

4.1 Common configuration properties

4.1.1 Site properties

The site.properties file tells JPF at startup time where to look for the pro-grams checked and extensions. Line 2 in listing 4.1 specifies the pathto the programs being tested. Line 5 specifies path to the JPF-core ex-tension. Finally, line 8 specifies the extensions that are being used forthe SUT. The site.properties file should be put in a .jpf folder under thehome directory on Unix systems and in Windows systems under thedirectory represented by the value of the standard Java system prop-erty user.home.

1 # JPF s i t e c o n f i g u r a t i o n2 j p f . home = /Users/JPF_HOME34 # path to extens ions5 j p f−core = $ { j p f . home}/ j p f−core67 # extens ion ( s )

27

Page 34: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

28 CHAPTER 4. RESULTS

8 extens ions=$ { j p f−core }

Listing 4.1: Site properties common for all systems under test

4.1.2 Project properties

Each JPF module contains a jpf.properties file in its root directory, nomatter if this is the JPF-core or an extension. System under test projectscan contain a jpf.properties file to factor out common settings (such asclass paths) for all JPF applications within this project. This file wasleft untouched for all systems under test.

4.1.3 Application properties

In order to run JPF, it must know what main class it should start toexecute. This is the minimal purpose of the *.jpf application propertiesfiles, which are part of the SUT. Line 2 in listing 4.2 specifies the mainclass. Line 5 specifies the path to the Java class files and line 6 to thesource files for SUT. The placement of the *.jpf file does not matter aslong as the paths are correctly set.

4.1.4 JPF Statistics

After each execution, JPF prints out statistics such as the executiontime and number of instructions. These are not considered in this re-port.

1 # JPF a p p l i c a t i o n c o n f i g u r a t i o n2 t a r g e t = C l i e n t34 # paths5 c l a s s p a t h =/Users/JPF_HOME/programs/SUT/bin6 sourcepath=/Users/JPF_HOME/programs/SUT/ s r c

Listing 4.2: Application properties common for all systems under test

Page 35: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

CHAPTER 4. RESULTS 29

4.2 Specific configuration properties

In this section JPF configurations for specific programs are presented.The programs considered are a server-client program called UDP-File-System-Query-Framework, a producer-consumer program, a reader-writerprogram, a program that solves the barber shop problem and lastlya program that simulates a restaurant but falls under the producer-consumer program type.

4.2.1 UDP-File-System-Query-Framework

Program description

This SUT is a server-client type of program written in about 400 linesof code. It consists of a server that awaits connecting clients throughsockets, and clients that send to the server a file. The server respondswith the last modification date of the sent file.

JPF configuration

The first step in the process of making the JPF decide if there are bugsin the program or not, is to install an extension that can handle dis-tributed programs, since JPF in its core module can not do this. Alook at existing JPF modules revealed that JPF-net-iocache fulfills therequirement.

To get JPF-net-iocache to work, the site.properties file must be up-dated to include the extension in its modules list. The extension wasalso added to the extensions list, as can be seen in listing 4.3. This isdone to register the extensions and make them a part of the JPF execu-tion.

1 j p f . home = /Users/JPF_HOME23 j p f−core = $ { j p f . home}/ j p f−core4 j p f−net−iocache = $ { j p f . home}/ j p f−net−iocache5 j p f−nhandler = $ { j p f . home}/ j p f−nhandler67 extens ions=$ { j p f−core } , $ { j p f−net−iocache }

Listing 4.3: The site properties for installing net-iocache and jpf-nhandler

Page 36: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

30 CHAPTER 4. RESULTS

Since JPF-net-iocache model checks one part of a distributed pro-gram while the other parts run normally, an application properties filemust be created for both the server and the client. The server programwas model checked first. In listing 4.4 can be seen the application prop-erties for the server program. Line 11 sets the classpath to the classesthat constitute JPF itself. The property jpf-net-iocache.boot.peer.command...on line 15 is used to choose the connecting client program. The valueof the line refers to a shell script that simply runs the client programthrough the java command. Line 17 and 18 sets arguments for the clientprograms.

1 @using = j p f−nhandler23 t a r g e t = Server45 c l a s s p a t h = /Users/JPF_HOME/programs/6 UDP−F i l e−System−Query−Framework/78 sourcepath = /Users/JPF_HOME/programs/9 UDP−F i l e−System−Query−Framework/

1011 n a t i v e _ c l a s s p a t h = /Users/JPF_HOME/j p f−nhandler/ l i b1213 nhandler . delegateUnhandledNative = true14 j p f−net−iocache . boot . peer . command=/Users/JPF_HOME/15 programs/UDP−F i l e−System−Query−Framework/ C l i e n t . sh1617 j p f−net−iocache . arg0 = l o c a l h o s t18 j p f−net−iocache . arg1 = README.md

Listing 4.4: The application properties for the server program.

To handle native methods, the extension JPF-nhandler was installed.The site.properties file was edited to include the new extension asseen in the line jpf-nhandler = $jpf.home, but following the JPF-nhandlerguide, the module was left out from the extensions list and was insteadincluded in the application properties.

With this configuration, the server program was run on the JPFand a client program was run on a different terminal on the JVM. JPFcommunicated with the client program and some native methods weredelegated but an error occurred that is seen in figure 4.1.

Page 37: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

CHAPTER 4. RESULTS 31

Figure 4.1: JPF error output when delegating a native method fails.

JPF-nhandler has some limitations when delegating native meth-ods that have their class modeled in the JPF package. If the modelclass internally uses methods that are not part of the original Java li-brary that is modeled, there is an error. An attempt was made to by-pass the model class that model the java.nio library which was causingthis problem but the problem remained.

4.2.2 Producer-consumer-instance-1

Program description

This program is an instance of the type producer-consumer.

JPF configuration

When checking this program no extensions where used. The JPF per-formed the check with its standard settings.

1 t a r g e t = Main2 c l a s s p a t h =/Users/JPF_HOME/programs/ProducerConsumer/bin3 sourcepath=/Users/JPF_HOME/programs/ProducerConsumer/ s r c

Listing 4.5: The configuration file

The JPF was able to find a bug, specifically a deadlock.

Page 38: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

32 CHAPTER 4. RESULTS

Figure 4.2: JPF found a deadlock

4.2.3 Reader-writer-instance-1

Program description

This program is an instance of the type reader-writer.

JPF configuration

When checking this program no extensions where used. The JPF per-formed the check with its standard settings.

1 t a r g e t = Main2 c l a s s p a t h =/Users/JPF_HOME/programs/ReaderWriter/bin3 sourcepath=/Users/JPF_HOME/programs/ReaderWriter/ s r c

Listing 4.6: The configuration file

The JPF ran out of memory.

Page 39: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

CHAPTER 4. RESULTS 33

Figure 4.3: JPF out of memory

4.2.4 Barber-shop-instance-1

Program description

This program is an instance of the type barber shop.

JPF configuration

When testing this program, no extensions where used and thereforethere were no configurations besides the default configurations of theJPF-core.

1 t a r g e t = Main2 c l a s s p a t h =/Users/JPF_HOME/programs/BarberShop/bin3 sourcepath=/Users/JPF_HOME/programs/BarberShop/ s r c

Listing 4.7: The configuration file

With this core setting the JPF found a deadlock.

Page 40: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

34 CHAPTER 4. RESULTS

Figure 4.4: JPF found a deadlock

4.2.5 Restaurant simulator

Program description

This program simulates a restaurant with a number of chefs, dishes,guests and tables. It is a producer-consumer type of program where anumber of chefs produce values that the guests consume.

JPF configuration

The site properties in listing 4.8 was used with the application proper-ties in listing 4.9 and the result in figure 4.5 was achieved.

1 j p f . home = /Users/JPF_HOME23 j p f−core = $ { j p f . home}/ j p f−core4 j p f−nhandler = $ { j p f . home}/ j p f−nhandler56 extens ions=$ { j p f−core }

Listing 4.8: The site properties

Page 41: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

CHAPTER 4. RESULTS 35

1 @using = j p f−nhandler23 t a r g e t = Restaurant4 t a r g e t . args = /Users/JPF_HOME/programs/Restaurant/ s r c /arg1 . t x t56 nhandler . delegateUnhandledNative = true78 c l a s s p a t h = /Users/JPF_HOME/programs/Restaurant/bin9

10 n a t i v e _ c l a s s p a t h = /Users/JPF_HOME/j p f−nhandler/ l i b1112 sourcepath = /Users/JPF_HOME/programs/Restaurant/ s r c1314 log . l e v e l = f i n e s t15 log . output=MyLog

Listing 4.9: The application properties

Figure 4.5: JPF error output for Restaurant.

What can be seen is that JPF terminates with no errors while theprogram crashes due to the exception java.lang.NoSuchMethodException.The application properties has some so far unseen properties. On line4 in listing 4.9 is seen the property for specifying arguments for themodel checked program. In this case the arguments specify the num-ber of chefs, tables, dishes and guests. The details are left out sincethe program does not go so far as to produce anything meaningful be-fore terminating. As with UDP-File-System-Query-Framework, line 10sets the classpath to the classes that constitute JPF itself. The two last

Page 42: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

36 CHAPTER 4. RESULTS

lines in this same file specifies the use of logging. The logger saves in-formation about what JPF is doing at various stages in the verificationprocess. Line 16 sets the granularity of the information logged and line17 sets the file were the log should be saved. Part of the log is seen infigure 4.6. Its content will be treated in the discussion.

Figure 4.6: A part of the JPF log output for Restaurant.

Page 43: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

Chapter 5

Discussion

In this section the results are analysed on the basis of programs us-ing and not using native methods. Then general results are discussedapplicable to both types of programs. Limitations encountered in thestudy follows, divided into a critique of the method, limitations of theJPF extensions and limitations of the JPF documentation.

5.1 Analysis of results

5.1.1 Programs with native methods

The two programs using native methods, the restaurant simulator andthe server-client program, failed on the basis of native methods eventhough JPF-nhandler was used for both SUTs. This means that no ex-amples were available where the server-client interaction could be ver-ified because the server program used failed with a native method be-fore the interaction with the client was completely verified. The nativemethod failure was due to the same cause in both cases. The JVM wastrying to load a method it could not find and threw a java.lang.NoSuch-MethodException.

In the case of the restaurant simulator the failure can be trackedthrough the produced log output, seen in figure 4.6. On line 9 theclass java.nio.Buffer is loaded from a jar file from within the JPF folder.This is a different place from where standard Java classes are loaded.JPF uses this jar to load so called model classes that JPF uses insteadof the Java library equivalent because these latter has native methodsin them. Before the creation of JPF-nhandler, users of JPF that had to

37

Page 44: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

38 CHAPTER 5. DISCUSSION

deal with native methods wrote model classes that simulated classeswith native methods. JPF still uses a model class instead of the orig-inal class if such a class exists. If the model class contains a methodthat does not exist in the standard Java library, an error will be thrownwhen JPF-nhandler reaches that method in the model class and del-egates it to JVM. In this case, it is the constructor to the Buffer classjava.nio.Buffer.<init>(IIII)V that is invoked, and right after this an ex-ception is loaded. It can be seen on line 42 in figure 4.6. It is not seenfrom the log output what happened to the constructor. That it wasdelegated remains a hypothesis. It is not clear where this constructorcomes from since an inspection into the jar file reveals no such con-structor in the model class java.nio.Buffer.

To solve the problem of inconsistency between original and modelclasses JPF-nhandler has a configuration property that skips chosenmethods. This configuration property was not applicable in this situa-tion since it was not possible to know the name of the invoked methodas the jar file for the model classes had no constructor for java.nio.Bufferthat matches the bytecode signature java.nio.Buffer.<init>(IIII)V.

5.1.2 Programs without native methods

The JPF found a deadlock when checking the programs producer-con-sumer-instance-1 and barber-shop-instance-1. However, this does not en-sure that there are no other bugs in the program due to the fact thatthe JPF stops executing when it founds an error. Therefore, it is notpossible to state that these programs are free from any other possiblebugs besides deadlocks.

When JPF checked the reader-writer-instance-1 program it ran out ofmemory after reaching over 9000 program states. In order to cut theamount of program states the source code of the program where mod-ified. The for loop that created several threads where totally removedfrom the source code. The program were then recompiled and checkedby the JPF. This time, it found no errors. It should be noted that remov-ing the entire for loop is a modification that affects the characteristicsof the program. The point with this specific program is that there areseveral writers and readers. Therefore, the output of JPF after runningwith these modifications where not attached to the result.

Page 45: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

CHAPTER 5. DISCUSSION 39

5.1.3 General results

The distinction of programs into different types did not always reflectdifferences in JPF configuration. Rather, some types that at the outsetwere interpreted as different could be gathered under the same type.This is the case for the types producer-consumer and reader-writer.These could fall into the common type of solutions to classical syn-chronization problems. Even then, what distinguishes this type fromthe remaining one, server-client, is not a positive characteristic but theabsence of server-client interaction. In retrospect a more natural typedistinction would be between programs that use different kinds of ex-tension. A type distinction could therefore be programs that use nativemethods, programs that use server-client interaction and then the re-maining class of program types that can not be categorized into any ofthese types. With this argument, it is not a preexisting program typethat decides the kind of JPF configuration, but on the contrary, JPFextensions that decides the program type. This necessitates the userto have a good understanding of the available extensions in order toclassify the type of program to be verified.

It is not known if the use of a synchronization technique employingwait() and notify() impacted the choice of JPF configuration. If adifferent synchronization technique demanded a greater state spacethan the technique employed, the technique would need complemen-tary configuration properties to curb the state space explosion.

The number of results that we have is too small to make any state-ment about general configuration patterns for any type of programexcept if by type one means the difference between a program thatuses native methods and one that does not. The conclusion will showwhat JPF configuration properties are constant for all programs us-ing wait() and notify() and what properties are constant for thesubset of these same programs using native methods. Note that con-stant set of properties does not necessarily here mean sufficient setof properties. Although the conclusion will show the minimum setof configuration properties needed for JPF to terminate with or with-out specifically concurrency errors, these does not entail that they areenough for JPF to terminate this way but that the properties must bepresent for JPF to do so. For some programs that were model checked,the concluding set of properties are nevertheless sufficient for requiredtermination.

Page 46: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

40 CHAPTER 5. DISCUSSION

The variation of properties for the model checked programs wassmall. This makes it possible to create a general use case that is appli-cable to a large variety of programs. But it should be kept in mind thatthese constants might change for larger programs.

5.2 Limitations and critique

5.2.1 Method critique

Although at the outset an obvious limitation of JPF is the state spaceof programs in practice, this limitation was not encountered. This isbecause no large Java programs were found with wait/notify syn-chronization. By large is meant programs with over a thousand linesof code. In theory JPF is supposed to handle programs up to ten thou-sand lines of code. The programs studied were a couple of hundredlines of code. A better approach would be to already at the outset havelarge programs to model check. An interesting example would be amarket ready program. Such a program, as for instance a word pro-cessor, would challenge the JPF to perform at its edge. At this bound-ary case, it would be easier to draw conclusions about what config-uration patterns produce what kind of outcome. Another possibilitywith a market ready program would be the study of how to isolatedifferent parts of the program to be model checked. The question ofhow to separate a part of the program while still keeping its core func-tionality becomes here an important factor in the verification process.This would generalize the current problem statement to include writ-ing suitable SUTs, and show if different configurations of JPF impactsthe way smaller programs can be isolated from larger ones.

Searching for programs with the requirements that it must be a Javaprogram containing wait() and notify()methods proved difficult.Although platforms like GitHub and BitBucket provide some searchfunctionality, they do not fully meet our requirements. For instance,only readme files and small files at a couple of hundred lines of codeare searchable at GitHub. Only program descriptions were searchableat BitBucket as the advanced search there seemed to be down at theresearch time. This made it difficult to find different implementationsof each type of program.

Page 47: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

CHAPTER 5. DISCUSSION 41

5.2.2 Extensions

Extensions formed an important concern of the method. In fact, thevery first issue to be tackled in verification is the decision about whetherthe core of JPF is sufficient for the needs at hand. In this consider-ation, weight must be given to what it is in the verification that issought after. If the engineer suspects that races can frequently oc-cur, it is not enough to use JPF-core for race finding but the extensionJPF-racefinder must be installed. A good point to keep in mind is tobrowse the available extensions at this stage of reasoning. Often thename of the extension gives significant data about what it does. To-day, the number of extensions is not so large, so a quick browse overall available extensions is possible. In the future, a search mechanismfor finding suitable extensions for particular requirements will be nec-essary.

The biggest problem with extensions is that they are often not wellsupported. Some extensions encountered at the JPF homepage havebeen deprecated and are no longer supported for the latest version ofJPF. This was the case with the extension JPF-concurrent. The waysuch limitations are discovered is also a problem. In the case of JPF-concurrent a note was found in a comment section on the web that theextension contains a bug and is no longer supported. Such informationshould be in the homepage. As it is now, much time for an engineer isspent gathering scattered facts about if and how an extension works.

5.2.3 Usability and documentation

Once the general structure of JPF is understood, actually using it isstraight forward. This is not apparent by the documentation. Theunderstanding of JPF would be quicker if the documentation beganwith complete and thorough use cases where the entire process from aconfiguration to JPF runs are exemplified. As it stands, the documen-tation reflects the highly modular character of JPF itself. A numberof complete use cases would bypass this impression and put the userright in front of the practical issues facing him or her. The deeper the-ory behind model checking and the inner workings of JPF should beabstracted as much as possible from using it. The inner mechanismsshould be exposed as the verification requirements become more com-plex. For simple cases like verifying a solution to the producer-con-sumer problem, JPF could behave like any black box instrument, sim-

Page 48: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

42 CHAPTER 5. DISCUSSION

ply taking a program as input and producing an output. The impres-sion of the complexity of JPF is one of its main disadvantages. Theconfiguration patterns presented in the conclusion forms suggestionstoward a more thorough and complete general use case scenario tointroduce new users to JPF.

At the end of the project a number of additional configuration op-tions were presented by Cyrille Artho that determines internal JPFfunctions. These options are not available in the JPF documentationwhich exemplifies in another way that it is incomplete. A web searchwill reveal scattered discussions about these options on various places.The options are presented in listing 5.1 for the user who wishes to ex-plore them further.

1 cg . boolean . f a l s e _ f i r s t = true2 cg . b re ak_ s i ng l e_ ch o ic e = f a l s e3 cg . enable_atomic = true4 cg . enumerate_random = f a l s e5 cg . max_processors = 16 cg . randomize_choices = NONE7 cg . seed = 428 cg . threads . break_arrays = f a l s e9 cg . threads . break_sleep = true

10 cg . threads . b r e a k _ s t a r t = true11 cg . threads . break_yie ld = true

Listing 5.1: Additional configuration options for changing the internalfunctioning of the JPF.

Page 49: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

Chapter 6

Conclusion

This report has found general configuration patterns concerning ap-plication properties for programs without native methods. It has alsofound a general configuration pattern for programs with native meth-ods but it does not lead to the required goal that JPF terminates withor without specifically concurrency errors. This configuration patternneeds additional adjustments from the user. Another general patternhas been found for site properties that can be used by both types ofprograms. For the set of programs without native methods, the appli-cation and site properties presented below are sufficient properties fortwo out of three programs in this study, that enables JPF to terminatein the required way.

The general configuration pattern arrived at for site properties isseen in listing 6.2 and the general configuration pattern regarding ap-plication properties for programs not using native methods is seen inlisting 6.1.

1 j p f . home = /Users/JPF_HOME23 j p f−core = $ { j p f . home}/ j p f−core45 extens ions=$ { j p f−core }

Listing 6.1: The site properties for a general use case.

43

Page 50: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

44 CHAPTER 6. CONCLUSION

1 t a r g e t = SystemUnderTest23 c l a s s p a t h = /Users/JPF_HOME/SystemUnderTest4 sourcepath = /Users/JPF_HOME/SystemUnderTest

Listing 6.2: The application properties for a general use case.

For the site properties, each extension is added in a separate rowunder line 3 and possibly on the extensions row on line 5 if the "@us-ing = ... " property is not used in the application properties, as used inlisting 6.3. An example of a site properties configured with extensionscan be seen in the result for the UDP-File-System-Query-Framework pro-gram in listing 4.3.

As for programs that use native methods, the general applicationproperty file looks like in listing 6.3.

1 @using = j p f−nhandler23 t a r g e t = SystemUnderTest45 c l a s s p a t h = /Users/JPF_HOME/SystemUnderTest6 sourcepath = /Users/JPF_HOME/SystemUnderTest7 n a t i v e _ c l a s s p a t h = /Users/JPF_HOME/j p f−nhandler/ l i b89 nhandler . delegateUnhandledNative = true

Listing 6.3: The application properties for a general use case employ-ing native methods.

With this configuration it is not certain that JPF will reach a concur-rency bug or finish without errors. A problem arrived at is connectedwith the use of the Scanner class in Java’s standard library. This classcalls CharBuffer which in turn tries to resolve the constructor for theBuffer class. The constructor called is one that does not exist in the JPFmodel class which makes JPF throw a NoSuchMethodException. Theuser that needs to use the Scanner class therefore needs to prepare tomanually rewrite a model class in the JPF library so that its fields andsuperclasses are consistent with the original class. According to Shafieiand Breugel [19] this is not a trivial assignment. This work thereforeconcludes that fixing the model class inconsistency problem relative

Page 51: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

CHAPTER 6. CONCLUSION 45

to the original class is a major obstacle to making JPF a more usefultool for engineers working with concurrent Java programs using onlywait() and notify().

Page 52: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

Bibliography

[1] Remzi H Arpaci-Dusseau and Andrea C Arpaci-Dusseau. Oper-ating systems: Three easy pieces. Arpaci-Dusseau, 2015.

[2] Cyrille Artho et al. “Efficient model checking of networked ap-plications”. In: International Conference on Objects, Components,Models and Patterns. Springer. 2008, pp. 22–40.

[3] Güenther Brand. Java Pathfinder JPF2 Second Generation of JavaModel Checker. 2004.

[4] Edmund M. Clarke. “The birth of model checking”. In: 25 Yearsof Model Checking (2008), pp. 1–26.

[5] Edmund M. Clarke, E Allen Emerson, and Joseph Sifakis. “Modelchecking: algorithmic verification and debugging”. In: Commu-nications of the ACM 52.11 (2009), pp. 74–84.

[6] Pedro De Carvalho Gomes, Dilian Gurov, and Marieke Huis-man. “Specification and Verification of Synchronization with Con-dition Variables”. In: Fifth International Workshop on Formal Tech-niques for Safety-Critical Systems (FTSCS 2016). 2016, p. 3.

[7] Vijay D’silva, Daniel Kroening, and Georg Weissenbacher. “Asurvey of automated techniques for formal software verification”.In: IEEE Transactions on Computer-Aided Design of Integrated Cir-cuits and Systems 27.7 (2008), pp. 1165–1178.

[8] Ericsson. “Erlang/OTP System Documentation”. In: AutomatedSoftware Engineering 10.2 (2003), pp. 203–232.

[9] Seth Goldstein. Concurrent Programming. 2013. URL: https://www.cs.cmu.edu/afs/cs/academic/class/15213-s13/www/lectures/23-concurrent-programming.pdf(visited on 03/30/2017).

46

Page 53: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

BIBLIOGRAPHY 47

[10] Klaus Havelund, Mike Lowry, and John Penix. “Formal analysisof a space-craft controller using SPIN”. In: IEEE Transactions onSoftware Engineering 27.8 (2001), pp. 749–765.

[11] Charles Antony Richard Hoare. “An axiomatic basis for com-puter programming”. In: Communications of the ACM 12.10 (1969),pp. 576–580.

[12] Gerard J. Holzmann. “The model checker SPIN”. In: IEEE Trans-actions on software engineering 23.5 (1997), pp. 279–295.

[13] Mykola Koshlatyi. Classical Synchronization Problems. 2016. URL:github.com/Koshlatyi-ML/ClassicalSynchronizationProblems(visited on 03/30/2017).

[14] Rustan Leino, Peter Müller, and Jan Smans. “Deadlock-free chan-nels and locks”. In: European Symposium on Programming. Springer.2010, pp. 407–426.

[15] Shan Lu et al. “Learning from Mistakes: A Comprehensive Studyon Real World Concurrency Bug Characteristics”. In: SIGOPSOper. Syst. Rev. 42.2 (Mar. 2008), pp. 329–339.

[16] Sottile Matthew, Timothy G. Mattson, and Craig Rasmussen. In-troduction to Concurrency in Programming Languages. CRC Press,2009.

[17] Robin Milner. Logic for computable functions description of a machineimplementation. Tech. rep. DTIC Document, 1972.

[18] Ames Research Center. JPF Documentation. 2017. URL: http://javapathfinder.sourceforge.net (visited on 02/27/2017).

[19] Nastaran Shafiei and Franck van Breugel. “Automatic handlingof native methods in Java PathFinder”. In: Proceedings of the 2014International SPIN Symposium on Model Checking of Software. ACM.2014, pp. 97–100.

[20] Herb Sutter and James Larus. “Software and the ConcurrencyRevolution”. In: Queue - Multiprocessors 3.7 (2005), pp. 56–57.

[21] Willem Visser et al. “Model checking programs”. In: AutomatedSoftware Engineering 10.2 (2003), pp. 203–232.

Page 54: Configuring Java Pathfinder for concurrent Java programskth.diva-portal.org/smash/get/diva2:1105877/FULLTEXT01.pdf · a Java program and its corresponding configuration file. The

www.kth.se