56
272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Embed Size (px)

Citation preview

Page 1: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

272: Software Engineering Fall 2012

Instructor: Tevfik Bultan

Lecture 2: Software Verification with JPF, ALV and Design for Verification

Page 2: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Model Checking Evolution

• Earlier model checkers had their own input specification languages– For example Spin, SMV

• This requires translation of the system to be verified to the input langauge of the model checker– Most of the time these translations are not automated and use ad-

hoc simplifications and abstractions• More recently several researchers developed tools for model

checking programs– These model checkers work directly on programs, i.e., their input

language is a programming language– These model checkers use well-defined techniques for restricting

the state space or use automated abstraction techniques

Page 3: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Explicit-State Model Checking Programs

• Verisoft from Bell Labs– C programs, handles concurrency, bounded search, bounded

recursion. – Uses stateless search and partial order reduction.

• Java Path Finder (JPF) at NASA Ames– Explicit state model checking for Java programs, bounded search,

bounded recursion, handles concurrency. – Uses techniques similar to the techniques used in Spin.

• CMC from Stanford for checking systems code written in C

Page 4: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Symbolic Model Checking of Programs

• CBMC – This is the bounded model checker we discussed earlier, bounds

the loop iterations and recursion depth.– Uses a SAT solver.

• SLAM project at Microsoft Research– Symbolic model checking for C programs. Can handle unbounded

recursion but does not handle concurrency. – Uses predicate abstraction and BDDs.

Page 5: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Java Path Finder

• Program checker for Java• Properties to be verified

– Properties can be specified as assertions• static checking of assertions

– It can also verify LTL properties• Implements both depth-first and breadth-first search and looks for

assertion violations statically• Uses static analysis techniques to improve the efficiency of the

search• Requires a complete Java program• It can only handle pure Java, it cannot handle native code

Page 6: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Java Path Finder, First Version

• First version – a translator from Java to PROMELA– Use SPIN for model checking

• Since SPIN cannot handle unbounded data– Restrict the program to finite domains

• A fixed number of objects from each class• Fixed bounds for array sizes

• Does not scale well if these fixed bounds are increased

• Java source code is required for translation

Page 7: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Java Path Finder, Current Version

• Current version of the JPF has its own virtual machine: JVM-JPF– Executes Java bytecode

• can handle pure Java but can not handle native code– Has its own garbage collection– Stores the visited states and stores current path – Offers some methods to the user to optimize verification

• Traversal algorithm – Traverses the state-graph of the program– Tells MC-JVM to move forward, backward in the state space, and evaluate the assertion

• The rest of the slides on the current version of JPF

Page 8: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Storing the States

• JPF implements a depth-first search on the state space of the given Java program– To do depth first search we need to store the visited states

• There are also verification tools which use stateless search such as Verisoft

• The state of the program consists of– information for each thread in the Java program

• a stack of frames, one for each method called– the static variables in classes

• locks and fields for the classes– the dynamic variables (fields) in objects

• locks and fields for the objects

Page 9: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Storing States Efficiently

• Since different states can have common parts each state is divided to a set of components which are stored separately– locks, frames, fields

• Keep a pool for each component– A table of field values, lock values, frame values

• Instead of storing the value of a component in a state store an index at which the component is stored in the table in the state– The whole state becomes an integer vector

• JPF collapses states to integer vectors using this idea• This strategy enables JPF to collapse and uncollapse parts of the

states during the state space exploration

Page 10: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

State Space Explosion

• State space explosion if one of the major challenges in model checking

• The idea is to reduce the number of states that have to be visited during state space exploration

• Here are some approaches used to attack state space explosion– Symmetry reduction

• search equivalent states only once – Partial order reduction

• do not search thread interleavings that generate equivalent behavior

– Abstraction• Abstract parts of the state to reduce the size of the state

space

Page 11: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Symmetry Reduction

• Some states of the program may be equivalent– Equivalent states should be searched only once

• Some states may differ only in their memory layout, the order objects are created, etc. – these may not have any effect on the behavior of the program

• JPF makes sure that the order which the classes are loaded does not effect the state – There is a canonical ordering of the classes in the memory

• A similar problem occurs for location of dynamically allocated objects in the heap– If we store the memory location as the state, then we can miss

equivalent states which have different memory layouts– JPF tries to remedy this problem by storing some information

about the new statements that create an object and the number of times they are executed

Page 12: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Partial Order Reduction

• Statements of concurrently executing threads can generate many different interleavings– all these different interleavings are allowable behavior of the

program• A model checker has to check all possible interleavings that the

behavior of the program is correct in all cases – However different interleavings may generate equivalent

behaviors• In such cases it is sufficient to check just one interleaving without

exhausting all the possibilities– This is called partial order reduction

Page 13: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

class S1 { int x;}class FirstTask extends Thread { public void run() { S1 s1; int x = 1; s1 = new S1(); x = 3;}}

class Main { public static void main(String[] args) { FirstTask task1 = new FirstTask(); SecondTask task2 = new SecondTask(); task1.start(); task2.start();}}

class S2 { int y;}class SecondTask extends Thread { public void run() { S2 s2; int x = 1; s2 = new S2(); x = 3;}}

state space search generates 258 stateswith symmetry reduction: 105 stateswith partial order reduction: 68 stateswith symmetry reduction + partial order reduction : 38 states

Page 14: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Action Language and Action Language Verifier

• Now, I want to talk about an infinite state model checker called Action Language Verifier (ALV)

• ALV is like Spin and SMV, it has its own input language called Action Language

• So, to verify something using ALV you first have to specify it in Action Language

Page 15: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Action Language

• Actions specify state changes (transitions)• States correspond to valuations of variables

– boolean– enumerated– integer (possibly unbounded)– heap variables (i.e., pointers)

• Parameterized constants – specifications are verified for every possible value of the constant

• Parameterized specifications– Enable verification of a protocols for arbitrary number of

processes

Page 16: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Action Language

• Transition relation is defined using actions– Atomic actions: Predicates on current and next state variables– Action composition:

• asynchronous (|) or synchronous (&)• Modular

– Modules can have submodules– A module is defined as asynchronous and/or synchronous

compositions of its actions and submodules

Page 17: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Actions in Action Language

• Atomic actions: Predicates on current and next state variables– Current state variables: reading, nr, busy– Next state variables: reading’, nr’, busy’– Logical operators: not (!) and (&&) or (||)– Equality: = (for all variable types)– Linear arithmetic: <, >, >=, <=, +, * (by a constant)

• An atomic action:

!reading and !busy and nr’=nr+1 and reading’

Page 18: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

What can we specify in Action Language?

• For example, we can specify a Read-Write lock implementation

• Then using Action Language Verifier, we can check if this read write lock satisfies a CTL property (like mutual-exclusion)

integer nr;

boolean busy;

initial: !busy and nr=0;

r_enter: [!busy] nr := nr+1;

r_exit: nr := nr-1;

w_enter: [!busy && nr=0] busy := true;

w_exit: busy := false;

Page 19: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Read-Write Lock in Action Languagemodule main()

integer nr; boolean busy; restrict: nr>=0; initial: nr=0 and !busy;

module ReaderWriter() enumerated state {idle, reading, writing}; initial: state=idle;

r_enter: state=idle and !busy and nr’=nr+1 and state’=reading;

r_exit: state=reading and nr’=nr-1 and state’=idle;

w_enter: state=idle and !busy and nr=0 busy’ and state’=writing;

w_exit: state=writing and !busy’ and state’=idle;

ReaderWriter: r_enter | r_exit | w_enter | w_exit; endmodule main: ReaderWriter*();

spec: invariant(busy => nr=0) spec: invariant(busy => eventually(!busy))

endmodule

S : Cartesian product ofS : Cartesian product of

variable domains defines variable domains defines

the set of statesthe set of states

I : Predicates defining I : Predicates defining the initial statesthe initial states

R : Atomic actions ofR : Atomic actions of a single processa single process

R : Transition R : Transition relation of a relation of a process, defined as process, defined as asynchronous asynchronous composition of its composition of its atomic actionsatomic actions

R : Transition relation of main, defined as asynchronous R : Transition relation of main, defined as asynchronous composition of finite but arbitrary number of reader-writer modulescomposition of finite but arbitrary number of reader-writer modules

Page 20: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Arbitrary Number of Threads?

• How do we check arbitrary number of threads?

• Counting abstraction– Create an integer variable for each thread state– Each variable counts the number of threads in a particular state– Generate updates and guards for these variables based on the

specification– Local states of the threads have to be finite

• Shared variables can be unbounded

• Counting abstraction is automated

Page 21: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Parameterized Read-Write Lockmodule main() integer nr; boolean busy; parameterized integer numReaderWriter; restrict: nr>=0 and numReaderWriter>=1; initial: nr=0 and !busy;

module ReaderWriter() integer idle, reading, writing; initial: idle=numReaderWriter;

r_enter: idle>0 and !busy and nr’=nr+1 and idle’=idle-1 and reading’=reading+1; r_exit: reading>0 and nr’=nr-1 and reading’=reading-1 and idle’=idle+1; w_enter: idle>0 and !busy and nr=0 and busy’ and idle’=idle-1 and writing’=writing+1; w_exit: writing>0 and !busy’ and writing’=writing-1 and idle’=idle+1 ReaderWriter: r_enter | r_exit | w_enter | w_exit; endmodule

main: ReaderWriter();

spec: invariant(busy => nr=0) spec: invariant(busy => eventually(!busy)) endmodule

Page 22: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Action Language Verifier

• Action Language Verifier is an infinite state model checker that can verify properties of systems specified in Action Language

• The input Action Language specification is represented as a transition system:– S : The set of states– I S : The set of initial states– R S S : The transition relation

• Properties of the input specification are expressed in temporal logics• Invariant(p) : is true in a state if property p is true in every state

reachable from that state– Also known as AG

• Eventually(p) : is true in a state if property p is true at some state on every execution path from that state– Also known as AF

Page 23: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Symbolic Model Checking

Given a program and a temporal property p:• Either show that all the initial states satisfy the temporal property p

– set of initial states truth set of p• Or find an initial state which does not satisfy the property p

– a state set of initial states truth set of p

• We can check these in two ways:– Starting from the initial states and iteratively add states that are

reachable from the current set of reachable states. We stop when there is nothing new to add. (This is called forward fixpoint computation). This computes all the reachable states.

OR– Start from the bad states (p) and iteratively add states that can

reach the current set of states. We stop when there is nothing new to add. (This is called backward fixpoint computation). This computes all the states that can reach a bad state.

Page 24: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

• • •• • •

Invariant(Invariant(pp))

ppInitialInitial

statesstates

initial states that initial states that

violate Invariant(violate Invariant(pp))

BackwardBackward

fixpointfixpoint

ForwardForward

fixpointfixpointInitialInitial

statesstates

• • •• • •

states that can reach states that can reach pp

i.e., states that violate Invariant(i.e., states that violate Invariant(pp))

reachable states reachable states

of the systemof the system

pp

Pre-conditionPre-condition ( (backwardImage)backwardImage)

of of pp

reachable states reachable states

that violate that violate ppPost-conditionPost-condition

(forward image)(forward image)

of initial statesof initial states

Symbolic Model Checking Computes Fixpoints

Page 25: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Symbolic Model Checking

• Represent sets of states and the transition relation as logic formulas • Forward and backward fixpoints can be computed by iteratively

manipulating these formulas– Pre- and Post-condition computation (aka Forward, backward

image): Existential variable elimination– Conjunction (intersection), disjunction (union) and negation (set

difference), and equivalence check

• Requires use an efficient data structures for manipulation of logic formulas

Page 26: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Fixpoints May Not Converge

• For infinite state systems fixpoint computations may not converge (there is always something new to add, so we never stop).

• In fact many verification problems are undecidable for infinite state systems

• So we use conservative approximations

Page 27: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Conservative Approximations

• Compute a lower ( p ) or an upper ( p+ ) approximation to the truth set of the property ( p )

• Action Language Verifier can give three answers:

IIpppp

1) “The property is satisfied”

II pp

3) “I don’t know”

2) “The property is false and here is a counter-example”

II pp ppsates whichsates which

violate the violate the

propertypropertyp+p+

pp

Page 28: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Action Language Tool Set

Action LanguageAction Language

ParserParser

Action LanguageAction Language

VerifierVerifier

Omega Omega

LibraryLibrary

CUDDCUDD

PackagePackageMONAMONA

Composite Symbolic LibraryComposite Symbolic Library

PresburgerPresburger

ArithmeticArithmetic

ManipulatorManipulator

BDDBDD

ManipulatorManipulator

AutomataAutomata

ManipulatorManipulator

Action LanguageAction Language

SpecificationSpecification

VerifiedVerified Counter Counter

exampleexample

Don’t Don’t

knowknow

Page 29: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Read-Write Lock Verification with ALV

Integers Booleans Cons. Time (secs.)

Ver. Time (secs.)

Memory (Mbytes)

RW-4 1 5 0.04 0.01 6.6

RW-8 1 9 0.08 0.01 7

RW-16 1 17 0.19 0.02 8

RW-32 1 33 0.53 0.03 10.8

RW-64 1 65 1.71 0.06 20.6

RW-P 7 1 0.05 0.01 9.1

Page 30: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Read-Write Lock in Javaclass ReadWriteLock {

  private Object lockObj;  private int totalReadLocksGiven;  private boolean writeLockIssued;  private int threadsWaitingForWriteLock;  public ReadWriteLock() {    lockObj = new Object();    writeLockIssued = false;  }    public void getReadLock() {    synchronized (lockObj) {      while ((writeLockIssued) || (threadsWaitingForWriteLock != 0)) {        try {          lockObj.wait();        } catch (InterruptedException e) {        }      }      totalReadLocksGiven++;    }  }  public void getWriteLock() {    synchronized (lockObj) {      threadsWaitingForWriteLock++;

      while ((totalReadLocksGiven != 0) || (writeLockIssued)) {        try {          lockObj.wait();        } catch (InterruptedException e) {          //        }      }      threadsWaitingForWriteLock--;      writeLockIssued = true;    }  }  public void done() {    synchronized (lockObj) {

      //check for errors      if ((totalReadLocksGiven == 0) && (!writeLockIssued)) {        System.out.println(" Error: Invalid call to release the lock");        return;      }      if (writeLockIssued)        writeLockIssued = false;      else        totalReadLocksGiven--;

      lockObj.notifyAll();    }

  }

}

How do we translate

this to Action Language?

Action Language

Verifier

Verification of Synchronization in

JavaPrograms

Page 31: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Two Challenges in Software Model Checking

• State space explosion– Exponential increase in the state space with increasing number of

variables and threads• State space includes everything: threads, variables, control

stack, heap

• Environment generation– Finding models for parts of software that are

• either not available for analysis, or• are outside the scope of the model checker

Page 32: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Modular Verification

• Modularity is key to scalability of any verification technique– Moreover, it can help in isolating the behavior you wish to focus

on, removing the parts that are beyond the scope of your verification technique

• Modularity is also a key concept for successful software design– The question is finding effective ways of exploiting the modularity

in software during verification

Page 33: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Interfaces for Modularity

• How do we do modular verification?– Divide the software to a set of modules– Check each module in isolation

• How do we isolate a module during verification/testing?– Provide stubs representing other modules (environment)

• How do we get the stubs representing other modules?– Write interfaces

• Interfaces specify the behavior of a module from the viewpoint of other modules

• Generate stubs from the interfaces

Page 34: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Interfaces and Modularity: Basic Idea

1. Write interface specifications for the modules

2. Automatically generate stubs from the interface specifications

3. Automatically generated stubs provide the environment during modular verification

Page 35: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

A Design for Verification Approach

Our design for verification approach is based on the following principles:

1. Use of design patterns that facilitate automated verification

2. Use of stateful, behavioral interfaces which isolate the behavior and enable modular verification

3. An assume-guarantee style modular verification strategy that separates verification of the behavior from the verification of the conformance to the interface specifications

4. A general model checking technique for interface verification

5. Domain specific and specialized verification techniques for behavior verification

Page 36: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

ControllerShared

Concurrency Controller Pattern

ThreadA

ThreadB

StateMachine

Controller

-var1-var2

+action1()+action2()

Action

+blocking()+nonblocking()-GuardedExecute

SharedStub

+a()+b()

Shared

+a()+b()

GuardedCommand

+guard()+update()

int GuardedCommand

ControllerStateMachine

+action1()+action2()

used at runtime

used during interface verification

used both times

Helper

classes

Page 37: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Concurrency Controller Pattern

• Avoids usage of error-prone Java synchronization primitives:

synchronize, wait, notify

• Separates controller behavior from the threads that use the controller– Supports a modular verification approach that exploits this

modularity for scalable verification

Page 38: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

class Action{ protected final Object owner; … private boolean GuardedExecute(){ boolean result=false; for(int i=0; i<gcV.size(); i++) try{ if(((GuardedCommand)gcV.get(i)).guard()){

((GuardedCommand)gcV.get(i)).update(); result=true; break; }

}catch(Exception e){} return result; } public void blocking(){ synchronized(owner) { while(!GuardedExecute()) { try{owner.wait();} catch (Exception e){} } owner.notifyAll(); } } public boolean nonblocking(){ synchronized(owner) { boolean result=GuardedExecute(); if (result) owner.notifyAll(); return result; } }}

class RWController implements RWInterface{

int nR; boolean busy;final Action act_r_enter, act_r_exit;final Action act_w_enter, act_w_exit;RWController() { ... gcs = new Vector(); gcs.add(new GuardedCommand() { public boolean guard(){

return (nR == 0 && !busy);} public void update(){busy = true;}} ); act_w_enter = new Action(this,gcs);}public void w_enter(){ act_w_enter.blocking();}public boolean w_exit(){ return act_w_exit.nonblocking();}public void r_enter(){ act_r_enter.blocking();}public boolean r_exit(){ return act_r_exit.nonblocking();}}

Reader-Writer ControllerThis helper class is

provided.No need to rewrite it!

Page 39: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Controller Interfaces

• A controller interface defines the acceptable call sequences for the threads that use the controller

• Interfaces are specified using finite state machines

public class RWStateMachine implements RWInterface{ StateTable stateTable; final static int idle=0,reading=1,writing=2; public RWStateMachine(){ ...

stateTable.insert("w_enter",idle,writing); } public void w_enter(){ stateTable.transition("w_enter"); } ...}writing

reading

idle

r_enter

r_exit

w_exit

w_enter

Page 40: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

InterfaceMachine

Thr

ead

1

Thr

ead

2

Thr

ead

n

Thr

ead

1

Controller

SharedData

InterfaceMachine

Thr

ead

2

InterfaceMachine

Thr

ead

n

Thread Modular Interface Verification

Concurrent Program

Controller Behavior

Modular

Behavior

Verification

Modular Design / Modular Verification

Interface

Page 41: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Behavior Verification

• Analyzing properties (specified in CTL) of the synchronization policy encapsulated with a concurrency controller and its interface– Verify the controller properties assuming that the user threads

adhere to the controller interface

• Behavior verification with Action Language Verifier– We wrote a translator which translates controller classes to Action

Language– Using counting abstraction we can check concurrency controller

classes for arbitrary number of threads

Page 42: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Interface Verification

• A thread is correct with respect to an interface if all the call sequences generated by the thread can also be generated by the interface machine– Checks if all the threads invoke controller methods in the order

specified in the interfaces – Checks if the threads access shared data only at the correct

interface states

Page 43: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Interface Verification

• Interface verification with Java PathFinder– Verify Java implementations of threads– Correctness criteria are specified as assertions

• Look for assertion violations• Assertions are in the StateMachine and SharedStub

– Performance improvement with thread Isolation• thread modular verification

Page 44: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Thread Isolation: Part 1

• Interaction among threads

• Threads can interact with each other in only two ways:– invoking controller actions– Invoking shared data methods

• To isolate the threads– Replace concurrency controllers with controller interface state

machines– Replace shared data with shared stubs

Page 45: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Thread Isolation: Part 2

• Interaction among a thread and its environment

• Modeling thread’s calls to its environment with stubs– File I/O, updating GUI components, socket operations, RMI call to

another program• Replace with pre-written or generated stubs

• Modeling the environment’s influence on threads with drivers– Thread initialization, RMI events, GUI events

• Enclose with drivers that generate all possible events that influence controller access

Page 46: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Concurrent Program

ControllerClasses

ThreadThreadThread

Classes

Controller InterfaceMachine

ControllerBehaviorMachine

JavaPath Finder

ActionLanguage

Verifier

Thread

Isolation

ThreadClass

Counting

Abstraction

Interface

Verification

Behavior

Verification

Verification Framework

Page 47: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

A Case Study: TSAFE

Tactical Separation Assisted Flight Environment (TSAFE) functionality:1. Display aircraft position2. Display aircraft planned route3. Display aircraft future projected route trajectory4. Show conformance problems between planned and projected

route

Page 48: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Server

Computation

FlightDatabase

GraphicalClient

Client

<<RMI>>

21,057 lines of code with 87 classes

Radar feed<<TCP/IP>>

User

EventThread

Feed Parser

Timer

TSAFE Architecture

Page 49: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Reengineering TSAFE

• Found all the synchronization statements in the code

(synchronize, wait, notify, notifyAll)

• Identified 6 shared objects protected by these synchronization statements

• Used 2 instances of a reader-writer controller and 3 instances of a mutex controller for synchronization

• In the reengineered TSAFE code the synchronization statements appear only in the Action helper class provided by the concurrency controller pattern

Page 50: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Behavior Verification Performance

RW 0.17 1.03

Mutex 0.01 0.23

Barrier 0.01 0.64

BB-RW 0.13 6.76

BB-Mutex 0.63 1.99

Controller Time(sec) Memory (MB) P-Time (sec) P-Memory (MB)

8.10 12.05

0.98 0.03

0.01 0.50

0.63 10.80

2.05 6.47

P denotes parameterized verification for arbitrary number of threads

Page 51: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Interface Verification Performance

Thread Time (sec) Memory (MB)

TServer-Main 67.72 17.08

TServer-RMI 91.79 20.31

TServer-Event 6.57 10.95

TServer-Feed 123.12 83.49

TClient-Main 2.00 2.32

TClient-RMI 17.06 40.96

TClient-Event 663.21 33.09

Page 52: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Effectiveness in Finding Faults

• Created 40 faulty versions of TSAFE by fault seeding

• Each version had at most one interface fault and at most one behavior fault – 14 behavior and 26 interface faults

• Among 14 behavior faults ALV identified 12 of them– 2 uncaught faults were spurious

• Among 26 interface faults JPF identified 21 of them– 2 of the uncaught faults were spurious– 3 of the uncaught faults were real faults that were not caught by

JPF

Page 53: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Falsification Performance

TServer-RMI 29.43 24.74

TServer-Event 6.88 9.56

TServer-Feed 18.51 94.72

TClient-RMI 10.12 42.64

TClient-Event 15.63 12.20

Thread Time (sec) Memory (MB)

RW-8 0.34 3.26

RW-16 1.61 10.04

RW-P 1.51 5.03

Mutex-8 0.02 0.19

Mutex-16 0.04 0.54

Mutex-p 0.12 0.70

Concurrency Controller Time (sec) Memory (MB)

Page 54: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Conclusions

• ALV performance– Cost of parameterized verification was somewhere between

concrete instances with 8 and 16 threads– Falsification performance was better than verification

• Completeness of the controller properties– Effectiveness of behavior verification by ALV critically depends on

the completeness of the specified properties

• Concrete vs. parameterized behavior verification– When no faults are found, the result obtained with parameterized

verification is stronger – However for falsification we observed that concrete instances

were as effective as parameterized instances

Page 55: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Conclusions

• JPF performance– Typically falsification performance is better than verification

performance– In some cases faults caused execution of new code causing the

falsification performance to be worse than verification performance

• Thread isolation– Automatic environment generation for threads result in too much

non-determinism and JPF runs out of memory– Dependency analysis was crucial for mitigating this

• Deep faults were difficult to catch using JPF– Three uncaught faults were created to test this

Page 56: 272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 2: Software Verification with JPF, ALV and Design for Verification

Conclusions

• Unknown shared objects– The presented approach does not handle this problem– Using escape analysis may help

• We could not find a scalable and precise escape analysis tool

• Environment generation – This is the crucial problem in scalability of the interface verification– Using a design for verification approach for environment

generation may help