The Bandera Model Reduction Tools James Corbett Matthew Dwyer John Hatcliff Shawn Laubach Corina Pasareanu Robby Hongjun Zheng Faculty Students and Post-docs.

Slides:



Advertisements
Similar presentations
Copyright W. Howden1 Programming by Contract CSE 111 6/4/2014.
Advertisements

Abstraction of Source Code (from Bandera lectures and talks)
Semantics Static semantics Dynamic semantics attribute grammars
Automatic Verification Book: Chapter 6. What is verification? Traditionally, verification means proof of correctness automatic: model checking deductive:
Compilation 2011 Static Analysis Johnni Winther Michael I. Schwartzbach Aarhus University.
Ch 7 B.
Abstraction and Modular Reasoning for the Verification of Software Corina Pasareanu NASA Ames Research Center.
1 Symbolic Execution for Model Checking and Testing Corina Păsăreanu (Kestrel) Joint work with Sarfraz Khurshid (MIT) and Willem Visser (RIACS)
Carnegie Mellon University Java PathFinder and Model Checking of Programs Guillaume Brat, Dimitra Giannakopoulou, Klaus Havelund, Mike Lowry, Phil Oh,
Bandera: Extracting Finite-state Models from Java Source Code James C. Corbett (Hawai’i) Matthew B. Dwyer, John Hatcliff, Shawn Laubach, Corina S. Păsăreanu,
Software Model Checking for Embedded Systems PIs: Matthew Dwyer 1, John Hatcliff 1, and George Avrunin 2 Post-docs: Steven Seigel 2, Radu Iosif 1 Students:
Termination Proofs for Systems Code Andrey Rybalchenko, EPFL/MPI joint work with Byron Cook, MSR and Andreas Podelski, MPI PLDI’2006, Ottawa.
1 Carnegie Mellon UniversitySPINFlavio Lerda SPIN An explicit state model checker.
Program analysis Mooly Sagiv html://
Overview of program analysis Mooly Sagiv html://
Bandera Tool Set Presented by: Dor Nir. Outline Specification Language (LTL) Software verification problems Introduction to Bandera tool Set Bandera Specification.
Overview of program analysis Mooly Sagiv html://
Formal Verification of SpecC Programs using Predicate Abstraction Himanshu Jain Daniel Kroening Edmund Clarke Carnegie Mellon University.
Abstraction and Modular Reasoning for the Verification of Software Corina Pasareanu, October, 2001 Thesis Committee: Matthew Dwyer, Major Advisor David.
272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 4: SMT-based Bounded Model Checking of Concurrent Software.
1 ECE 453 – CS 447 – SE 465 Software Testing & Quality Assurance Instructor Kostas Kontogiannis.
Runtime Refinement Checking of Concurrent Data Structures (the VYRD project) Serdar Tasiran Koç University, Istanbul, Turkey Shaz Qadeer Microsoft Research,
Exercise Solutions 2014 Fall Term. Week 2: Exercise 1 public static Boolean repOK(Stack mystack) { if (mystack.capacity() < 0) { return false;
Bandera: Extracting Finite-state Models from Java Source Code James Corbett Matthew Dwyer John Hatcliff Shawn Laubach Corina Pasareanu Robby Hongjun Zheng.
Finding Feasible Counter-examples when Model Checking Abstracted Java Programs Corina S. Pasareanu, Matthew B. Dwyer (Kansas State University) and Willem.
Copyright 2001, Matt Dwyer, John Hatcliff, and Radu Iosif. The syllabus and all lectures for this course are copyrighted materials and may not be used.
Model construction and verification for dynamic programming languages Radu Iosif
An extensible and highly-modular model checking framework SAnToS Laboratory, Kansas State University, USA Matt Dwyer.
CIS 842: Specification and Verification of Reactive Systems Lecture 1: Course Overview Copyright 2001, Matt Dwyer, John Hatcliff, and Radu Iosif. The.
Software Model-checking: The SAnToS/Bandera Perspective Matt Dwyer John Hatcliff Principal Investigators Support US National.
ICS 313: Programming Language Theory Chapter 13: Concurrency.
1 CSEP590 – Model Checking and Automated Verification Lecture outline for August 6, 2003.
Bandera: Extracting Finite-state Models from Java Source Code. Paper By: James C. Corbett, Mathew Dwyer, John Hatcliff, Shawn Laubach, Corina Pasareanu,
CIS 842: Specification and Verification of Reactive Systems Lecture INTRO-Examples: Simple BIR-Lite Examples Copyright 2004, Matt Dwyer, John Hatcliff,
Copyright 2001, Matt Dwyer, John Hatcliff, and Radu Iosif. The syllabus and all lectures for this course are copyrighted materials and may not be used.
Tool-supported Program Abstraction for Finite-state Verification Matthew Dwyer 1, John Hatcliff 1, Corina Pasareanu 1, Robby 1, Roby Joehanes 1, Shawn.
Model-checking Concurrent Java Software Using the Bandera Tool Set Matthew Dwyer John Hatcliff Radu Iosif Yu Chen Georg Jung Todd Wallentine FacultyStudents.
Lecture 4 Introduction to Promela. Promela and Spin Promela - process meta language G. Holzmann, Bell Labs (Lucent) C-like language + concurrency dyamic.
This Week Lecture on relational semantics Exercises on logic and relations Labs on using Isabelle to do proofs.
1 Software Testing & Quality Assurance Lecture 13 Created by: Paulo Alencar Modified by: Frank Xu.
Tool-supported Program Abstraction for Finite-state Verification Matthew Dwyer 1, John Hatcliff 1, Corina Pasareanu 1, Robby 1, Roby Joehanes 1, Shawn.
Model-checking Concurrent Java Software Using the Bandera Tool Set Matthew Dwyer John Hatcliff Radu Iosif Hongjun Zheng Shawn Laubach Corina Pasareanu.
Today’s Agenda  Quiz 4  Temporal Logic Formal Methods in Software Engineering1.
Agenda  Quick Review  Finish Introduction  Java Threads.
Operational Semantics Mooly Sagiv Reference: Semantics with Applications Chapter 2 H. Nielson and F. Nielson
Mutual Exclusion -- Addendum. Mutual Exclusion in Critical Sections.
Secure Information Flow for Reactive Programming Paradigm Zhengqin Luo SAFA workshop 2009.
Java Thread Programming
Tutorial 2: Homework 1 and Project 1
Formal methods: Lecture
Authors :John Hatcliff and Mattew Dwyer presented by Slava Yablonovich
Model Checking Java Programs (Java PathFinder)
Abstraction of Source Code
Bandera: Extracting Finite-state Models from Java Code
Formal verification in SPIN
Reasoning About Code.
Reasoning about code CSE 331 University of Washington.
Automatic Verification
Space-Reduction Strategies for Model Checking Dynamic Software
Aspect Validation: Connecting Aspects and Formal Methods
Over-Approximating Boolean Programs with Unbounded Thread Creation
An explicit state model checker
A Refinement Calculus for Promela
CSE 153 Design of Operating Systems Winter 19
Abstraction, Verification & Refinement
Programming Languages and Compilers (CS 421)
Process/Thread Synchronization (Part 2)
Software Engineering and Architecture
The Bogor Model Checking Framework
Presentation transcript:

The Bandera Model Reduction Tools James Corbett Matthew Dwyer John Hatcliff Shawn Laubach Corina Pasareanu Robby Hongjun Zheng Faculty Students and Post-docs Roby Joehanes Ritesh Desai Venkatesh Ranganath Oksana Tkachuk

Bandera Architecture BIRC BIR Simulator Abstraction Engine Slicer Analyses Translators SPIN dSPIN SMV JPF Property Tool Java Jimple Parser Error Trace Display

Property-directed Slicing slicing criterion generated automatically from observables mentioned in the property backwards slicing automatically finds all components that might influence the observables. Source program Resulting slice Slice mentioned in property indirectly relevant

Slicing: A Simple Example Raise m to the power of n: init: m := 5; [init.1] n := 2; [init.2] result := 1; [init.3] goto test; test: if (n<1) [test.1] then end else loop; loop: result := result*m; [loop.1] n := n-1; [loop.2] goto test; [loop.3] end: return; [end.1] Slicing Criterion: C = { [loop.2] } init: n := 2; [init.2] goto test; test: if (n<1) [test.1] then end else loop; loop: n := n-1; [loop.2] goto test; [loop.3] end: return; [end.1] data dependence control dependence

Computing Slices: The Program Dependence Graph Approach init: m := 5; [init.1] n := 2; [init.2] result := 1; [init.3] goto test; test: if (n<1) [test.1] then end else loop; loop: result := result*m; [loop.1] n := n-1; [loop.2] goto test; [loop.3] end: return; [end.1] Source Program [init.1] [init.2] [init.3] [test.1] [loop.1] [loop.2] [loop.3] [end.1] CFG [init.1] [init.2] [init.3] [test.1] [loop.1] [loop.2] [loop.3] [end.1] PDG

Computing Slices: The Program Dependence Graph Approach init: m := 5; [init.1] n := 2; [init.2] result := 1; [init.3] goto test; test: if (n<1) [test.1] then end else loop; loop: result := result*m; [loop.1] n := n-1; [loop.2] goto test; [loop.3] end: return; [end.1] Source Program [init.1] [init.2] [init.3] [test.1] [loop.1] [loop.2] [loop.3] [end.1] CFG [init.1] [init.2] [init.3] [test.1] [loop.1] [loop.2] [loop.3] [end.1] PDG Slice set wrt Criterion C: {m | m * n where n in C}

Correction: notion of Projection Slicing Criterion: C = { [loop.2] } ([init.1], [m=0,n=0,result=0]) ([init.2], [m=5,n=0,result=0]) ([init.3], [m=5,n=2,result=0]) ([init.4], [m=5,n=2,result=1]) ([test.1], [m=5,n=2,result=1]) ([loop.1], [m=5,n=2,result=1]) ([loop.2], [m=5,n=2,result=5]) ([loop.3], [m=5,n=1,result=5]) ([test.1], [m=5,n=1,result=5]) ([loop.1], [m=5,n=1,result=5]) ([loop.2], [m=5,n=1,result=25]) ([loop.3], [m=5,n=0,result=25]) ([test.1], [m=5,n=0,result=25]) ([end.1], [m=5,n=0,result=25]) (halt, [m=5,n=0,result=25]) Source Program TraceResidual Program (Slice) Trace ([init.2], [n=0]) ([init.4], [n=2]) ([test.1], [n=2]) ([loop.2], [n=2]) ([loop.3], [n=1]) ([test.1], [n=1]) ([loop.2], [n=1]) ([loop.3], [n=0]) ([test.1], [n=0]) ([end.1], [n=0]) (halt, [n=0])

Scaling to Concurrency Features of Java What are the relevant notions of dependence? –Besides data and control dependence, we have… dependences due to indefinite delays (divergence, indefinite block) dependences due to defs/refs of shared variables dependences due to synchronization primitives What is the appropriate notion of correctness? –must consider reactive programs designed to run indefinitely –must handle non-determinism (from linear to branching traces)

A Simple Language with JVM Concurrency Primitives P Run Blocked Waiting Holds: Buffer Lock Data T1 p_obtain_lock: enter-monitor buffer; goto p_check; p_check: if (count=2) then p_wait else p_put; p_wait: wait buffer; goto p_check; p_put: /* put item */ count := count + 1; if (count=1) then p_wakeup else p_release_lock; p_wakeup: notify buffer; goto p_release_lock; p_release_lock: exit-monitor buffer; if 1 then p_obtain_lock else exit_p; exit_p: return; Producer: count /* shared variable */ buffer /* lock variable */

A Simple Language with JVM Concurrency Primitives p_obtain_lock: enter-monitor buffer; goto p_check; p_check: if (count=2) then p_wait else p_put; p_wait: wait buffer; goto p_check; p_put: /* put item */ count := count + 1; if (count=1) then p_wakeup else p_release_lock; p_wakeup: notify buffer; goto p_release_lock; p_release_lock: exit-monitor buffer; if 1 then p_obtain_lock else exit_p; exit_p: return; P Run Blocked Waiting Holds: Buffer Lock Data T1

A Simple Language with JVM Concurrency Primitives p_obtain_lock: enter-monitor buffer; goto p_check; p_check: if (count=2) then p_wait else p_put; p_wait: wait buffer; goto p_check; p_put: /* put item */ count := count + 1; if (count=1) then p_wakeup else p_release_lock; p_wakeup: notify buffer; goto p_release_lock; p_release_lock: exit-monitor buffer; if 1 then p_obtain_lock else exit_p; exit_p: return; P Run Blocked Waiting Holds: Buffer Lock Data P

A Simple Language with JVM Concurrency Primitives p_obtain_lock: enter-monitor buffer; goto p_check; p_check: if (count=2) then p_wait else p_put; p_wait: wait buffer; goto p_check; p_put: /* put item */ count := count + 1; if (count=1) then p_wakeup else p_release_lock; p_wakeup: notify buffer; goto p_release_lock; p_release_lock: exit-monitor buffer; if 1 then p_obtain_lock else exit_p; exit_p: return; P Run Blocked Waiting Holds: Buffer Lock Data P

A Simple Language with JVM Concurrency Primitives p_obtain_lock: enter-monitor buffer; goto p_check; p_check: if (count=2) then p_wait else p_put; p_wait: wait buffer; goto p_check; p_put: /* put item */ count := count + 1; if (count=1) then p_wakeup else p_release_lock; p_wakeup: notify buffer; goto p_release_lock; p_release_lock: exit-monitor buffer; if 1 then p_obtain_lock else exit_p; exit_p: return; P Run Blocked Waiting Holds: Buffer Lock Data P

A Simple Language with JVM Concurrency Primitives p_obtain_lock: enter-monitor buffer; goto p_check; p_check: if (count=2) then p_wait else p_put; p_wait: wait buffer; goto p_check; p_put: /* put item */ count := count + 1; if (count=1) then p_wakeup else p_release_lock; p_wakeup: notify buffer; goto p_release_lock; p_release_lock: exit-monitor buffer; if 1 then p_obtain_lock else exit_p; exit_p: return; P Run Blocked Waiting Holds: Buffer Lock Data Tk

A Simple Language with JVM Concurrency Primitives p_obtain_lock: enter-monitor buffer; goto p_check; p_check: if (count=2) then p_wait else p_put; p_wait: wait buffer; goto p_check; p_put: /* put item */ count := count + 1; if (count=1) then p_wakeup else p_release_lock; p_wakeup: notify buffer; goto p_release_lock; p_release_lock: exit-monitor buffer; if 1 then p_obtain_lock else exit_p; exit_p: return; P Run Blocked Waiting Holds: Buffer Lock Data Tk

A Simple Language with JVM Concurrency Primitives p_obtain_lock: enter-monitor buffer; goto p_check; p_check: if (count=2) then p_wait else p_put; p_wait: wait buffer; goto p_check; p_put: /* put item */ count := count + 1; if (count=1) then p_wakeup else p_release_lock; p_wakeup: notify buffer; goto p_release_lock; p_release_lock: exit-monitor buffer; if 1 then p_obtain_lock else exit_p; exit_p: return; P Run Blocked Waiting Holds: Buffer Lock Data P

A Simple Language with JVM Concurrency Primitives p_obtain_lock: enter-monitor buffer; goto p_check; p_check: if (count=2) then p_wait else p_put; p_wait: wait buffer; goto p_check; p_put: /* put item */ count := count + 1; if (count=1) then p_wakeup else p_release_lock; p_wakeup: notify buffer; goto p_release_lock; p_release_lock: exit-monitor buffer; if 1 then p_obtain_lock else exit_p; exit_p: return; P Run Blocked Waiting Holds: Buffer Lock Data P

A Simple Language with JVM Concurrency Primitives p_obtain_lock: enter-monitor buffer; goto p_check; p_check: if (count=2) then p_wait else p_put; p_wait: wait buffer; goto p_check; p_put: /* put item */ count := count + 1; if (count=1) then p_wakeup else p_release_lock; p_wakeup: notify buffer; goto p_release_lock; p_release_lock: exit-monitor buffer; if 1 then p_obtain_lock else exit_p; exit_p: return; P Run Blocked Waiting Holds: Buffer Lock Data P

A Simple Language with JVM Concurrency Primitives p_obtain_lock: enter-monitor buffer; goto p_check; p_check: if (count=2) then p_wait else p_put; p_wait: wait buffer; goto p_check; p_put: /* put item */ count := count + 1; if (count=1) then p_wakeup else p_release_lock; p_wakeup: notify buffer; goto p_release_lock; p_release_lock: exit-monitor buffer; if 1 then p_obtain_lock else exit_p; exit_p: return; Run Blocked Waiting Holds: Buffer Lock Data P

Semantics The program counter pc assigns to each thread t the node of t to be executed. The store S maps each variable to a value The run state table R maps each thread to to either true or false The blocked table B assigns to each pair (k,t) the number of times thread t needs to acquire lock k once it is unblocked The lock waiting table W assigns to each pair (k,t) the number of times thread t needs to acquire lock k once it is awakened The lock table L maps each held lock k to a pair (t,n) where t is the thread that currently holds k, and n is the number of times that t has acquired the lock Transitions on configurations of the form... (pc,S,R,B,W,L)

Now…. …on to the notions of dependence needed for Java concurrency

Divergence: Infinite Delay Conventional slicing algorithms can turn terminating (diverging) programs into terminating programs Conventional Slice

Divergence Dependence Divergence Preserving Slice Node n is divergence dependent on node m if (a) m is a pre-divergence point (the test of a loop), and (b) there exists a non-trivial path p from m to n such that no node along the path (excluding m, n) is a predivergence point. Divergence Dependence Divergence dependence

Interference Dependence Node n is interference-dependent on node m if (a) n and m are in different threads, and (b) there is a variable x such that x is assigned to at m and x is read by n. Interference Dependence Thread 1 (fragment)Thread 2 (fragment) M: x=y+3;N: y=x+3; Q: x=3; Consider slice criterion Implied Schedule X=3; y=3+x; x=y+3;

Synchronization Dependence Node n is synchronization-dependent on node m if m1 and m2 mark the enclosing monitor for n and m=m1 or m=m2. Synchronization Dependence n m2 m1 q2 q1 enter-monitor k2; exit-monitor k2; enter-monitor k1; exit-monitor k1;

Ready Dependence Node n is ready-dependent on node m if m’s failure to complete, e.g., because it is never reached, or because n is wait and the corresponding notify never occurs, or because n’s thread is blocked forever (trying to obtain a lock) can make the thread of n block before reaching or completing n --- thus delaying n’s execution indefinitely. Ready Dependence (intuition) m: enter-monitor k; … exit-monitor k; … n: x=e; Case 1: Thead(n) = Thread(m) and n is reachable from m in the CFG of Thread(n) and Code(m) = enter-monitor k.

Ready Dependence n: enter-monitor k; … exit-monitor k; … y=e1; Case 2: Thead(n) != Thread(m) and Code(n) = enter-monitor k and Code(m) = exit-monitor k. enter-monitor k; … m: exit-monitor k; … x=e2; Thread 1:Thread 2:

Ready Dependence Case 3: Thead(n) = Thread(m) and n is reachable from m in the CFG of Thread(n) and Code(m) = wait k. enter-monitor k; … m: wait k; … exit-monitor k; … n: x=e;

Ready Dependence Case 4: Thead(n) != Thread(m) and Code(n) = wait k and Code(m) = notify k. enter-monitor k; … n: wait k … exit-monitor k; … y=e1; enter-monitor k; … m: notify k; … exit-monitor k; … x=e2; Thread 1:Thread 2:

Assessment Most notions of dependence presented here can be optimized by further static analysis –redundant lock analysis –may/must happen in order/parallel –guaranteed-released lock analysis How do we know we have all the dependences?

Correctness Issues Generalization of conventional notion of projection based on weak-bisimulation! ([init.1], [m=0,n=0,result=0]) ([init.2], [m=5,n=0,result=0]) ([init.3], [m=5,n=2,result=0]) ([init.4], [m=5,n=2,result=1]) ([test.1], [m=5,n=2,result=1]) ([loop.1], [m=5,n=2,result=1]) ([loop.2], [m=5,n=2,result=5]) ([loop.3], [m=5,n=1,result=5]) ([test.1], [m=5,n=1,result=5]) ([loop.1], [m=5,n=1,result=5]) ([loop.2], [m=5,n=1,result=25]) ([loop.3], [m=5,n=0,result=25]) ([test.1], [m=5,n=0,result=25]) ([end.1], [m=5,n=0,result=25]) (halt, [m=5,n=0,result=25]) Source Program TraceResidual Program (Slice) Trace ([init.2], [n=0]) ([init.4], [n=2]) ([test.1], [n=2]) ([loop.2], [n=2]) ([loop.3], [n=1]) ([test.1], [n=1]) ([loop.2], [n=1]) ([loop.3], [n=0]) ([test.1], [n=0]) ([end.1], [n=0]) (halt, [n=0])

Abstraction Component Functionality Variable Concrete Type Abstract Type Inferred Type Abstraction Library Bandera Abstraction Specification Language BASL Compiler PVS Jimple Abstraction Engine Abstracted Jimple x y done count o b int bool Object Buffer int …. Signs intAbs Bool …. Point Buffer

Abstraction Specification abstraction Signs abstracts int begin TOKENS = { NEG, ZERO, POS }; abstract(n) begin n {NEG}; n == 0 -> {ZERO}; n > 0 -> {POS}; end operator + add begin (NEG, NEG) -> {NEG} ; (NEG, ZERO) -> {NEG} ; (ZERO, NEG) -> {NEG} ; (ZERO, ZERO) -> {ZERO} ; (ZERO, POS) -> {POS} ; (POS, ZERO) -> {POS} ; (POS, POS) -> {POS} ; (_,_)-> {NEG, ZERO, POS}; /* case (POS,NEG), (NEG,POS) */ end public class Signs { public static final int NEG = 0; // mask 1 public static final int ZERO = 1; // mask 2 public static final int POS = 2; // mask 4 public static int abstract(int n) { if (n < 0) return NEG; if (n == 0) return ZERO; if (n > 0) return POS; } public static int add(int arg1, int arg2) { if (arg1==NEG && arg2==NEG) return NEG; if (arg1==NEG && arg2==ZERO) return NEG; if (arg1==ZERO && arg2==NEG) return NEG; if (arg1==ZERO && arg2==ZERO) return ZERO; if (arg1==ZERO && arg2==POS) return POS; if (arg1==POS && arg2==ZERO) return POS; if (arg1==POS && arg2==POS) return POS; return Bandera.choose(7); /* case (POS,NEG), (NEG,POS) */ } Compiled

Specification Creation Tools abstraction Signs abstracts int begin TOKENS = { NEG, ZERO, POS }; abstract(n) begin n {NEG}; n == 0 -> {ZERO}; n > 0 -> {POS}; end operator + add begin (NEG, NEG) -> {NEG} ; (NEG, ZERO) -> {NEG} ; (ZERO, NEG) -> {NEG} ; (ZERO, ZERO) -> {ZERO} ; (ZERO, POS) -> {POS} ; (POS, ZERO) -> {POS} ; (POS, POS) -> {POS} ; (_,_)-> {NEG, ZERO, POS}; end Automatic Generation Forall n1,n2: neg?(n1) and neg?(n2) implies not pos?(n1+n2) Forall n1,n2: neg?(n1) and neg?(n2) implies not zero?(n1+n2) Forall n1,n2: neg?(n1) and neg?(n2) implies not neg?(n1+n2) Proof obligations submitted to PVS... Example: Start safe, then refine: +(NEG,NEG)={NEG,ZERO,POS}

Back End Bandera Intermediate Representation (BIR) –guarded command language –includes: locks, threads, references, heap –info to help translators (live vars, invisible) entermonitor r0 r1.count = 0; … loc s5: live { r0, r1 } when lockAvail(r0.lock) do { lock(r0.lock); } goto s6; loc s6: live { r1 } when true do invisible { r1.count = 0;} goto s7; Jimple BIR

Bounded Buffer BIR process BoundedB() BoundedBuffer_ref = ref { BoundedBuffer_col, BoundedBuffer_col_0 }; BoundedBuffer_rec = record { bound_ : range -1..4; head_ : range -1..4; tail_ : range -1..4; BIRLock : lock wait reentrant; }; BoundedBuffer_col : collection [3] of BoundedBuffer_rec; BoundedBuffer_col_0 : collection [3] of BoundedBuffer_rec; ……. ………. loc s34: live { b2, b1, add_JJJCTEMP_0, add_JJJCTEMP_6, add_JJJCTEMP_8 } when true do invisible { add_JJJCTEMP_8 := (add_JJJCTEMP_6 % add_JJJCTEMP_8); } goto s35; loc s35: live { b2, b1, add_JJJCTEMP_0, add_JJJCTEMP_8 } when true do { add_JJJCTEMP_0.head_ := add_JJJCTEMP_8; } goto s36; loc s36: live { b2, b1, add_JJJCTEMP_0 } when true do { notifyAll(add_JJJCTEMP_0.BIRLock); } goto s37; loc s37: live { b2, b1, add_JJJCTEMP_0 } when true do { unlock(add_JJJCTEMP_0.BIRLock); } goto s38;

Bounded Buffer Promela typedef BoundedBuffer_rec { type_8 bound_; type_8 head_; type_8 tail_; type_18 BIRLock; } … loc_25: atomic { printf("BIR: OK\n"); if :: (_collect(add_JJJCTEMP_0) == 1) -> add_JJJCTEMP_8 = BoundedBuffer_col. instance[_index(add_JJJCTEMP_0)].tail_; :: (_collect(add_JJJCTEMP_0) == 2) -> add_JJJCTEMP_8 = BoundedBuffer_col_0. instance[_index(add_JJJCTEMP_0)].tail_; :: else -> printf("BIR: NullPointerException\n"); assert(0); fi; goto loc_26; }

Bandera: When to Use It? When you want to check for event-sequencing properties in Java When you want to check simple invariants –Note: model-checking isn’t targeted to, e.g., proving the correctness of a sorting algorithm When you want to use slicing in automated/non-automated analysis of Java code When you want to use abstraction of source code for other purposes (e.g., testing) When you want to model-check Java using another model- checker not in Bandera (define a BIR backend) When you want to model-check code in an input language besides Java (write a translation to Jimple or BIR).

Bandera: Why are Others Interested? Funding from Honeywell, interest from Rockwell-Collins –possibly use as part of FAA certification Funding from NASA –interest in using model-checking to catch subtle bugs before deployment Funding from US NSF –interest in applied work on abstraction, support for formal methods in software engineering

Mars Pathfinder Mission Mission critical software: - Lander & rover-lander UHF communications - Data acquistion, image processing - Rover commands

Extensive Testing but… In first 15 (out of 92) days –there were 5 system resets –loss of data/time Bugs very difficult to diagnose –timing related defect –took days of simulation to reproduce

Current Status A reasonable subset of concurrent Java –not handled: recursive methods, exceptions, inner classes, native methods, libraries(*) Public release: November