Presentation is loading. Please wait.

Presentation is loading. Please wait.

Bogor Support US Army Research Office (ARO) US National Science Foundation (NSF) US Department of Defense Advanced Research Projects Agency (DARPA) Rockwell-Collins.

Similar presentations


Presentation on theme: "Bogor Support US Army Research Office (ARO) US National Science Foundation (NSF) US Department of Defense Advanced Research Projects Agency (DARPA) Rockwell-Collins."— Presentation transcript:

1 Bogor Support US Army Research Office (ARO) US National Science Foundation (NSF) US Department of Defense Advanced Research Projects Agency (DARPA) Rockwell-Collins ATC Boeing Lockheed Martin IBM An Extensible and Highly Modular Software Model-Checking Framework SAnToS Laboratory, Kansas State University, USA http://bogor.projects.cis.ksu.edu Matthew Dwyer John Hatcliff Robby Radu Iosif William Deng Edwin Rodriguez

2 Research Context Working on a variety of techniques static analysis, model-checking, run-time monitoring code level, architectural design level Aiming for robust tools built on solid semantic foundations open source, close to commercial quality Interacting intensively with domain experts research teams at Boeing (St. Louis), Rockwell-Collins, and Lockheed-Martin real-time middleware developers (Vanderbilt, Wash U (ACE-TAO), UC Irvine (Zen) Integration into development process ease of use and scalability sometimes take precedence over theoretical elegance most of the time, focus is on bug-finding rather than true verification SAnToS Laboratory, Kansas State University http://www.cis.ksu.edu/santos

3 Broad Overview being rebuilt from the ground up testing on significant code bases core model-checking engine technical work heap/thread symmetry sophisticated partial-order reductions for OO software large collection of course materials meta-modeling & software architectures variety of development tools for CCM, EJB, DRE Component Models (PRiSM from Boeing) dependency analysis techniques for concurrent Java and architectural designs security (information flow) applications automatic customization tools Indus

4 Bogor

5 Bogor – Software Model Checking Framework

6 Bogor – Direct support for OO software unbounded dynamic creation of threads and objects automatic memory management (garbage collection) virtual methods, … …, exceptions, etc. supports virtually all of Java thread & heap symmetry compact state representation partial order reduction techniques driven by object escape analysis locking information Extensive support for checking concurrent OO software Direct support for… Software targeted algorithms…

7 Tool Development Framework Bogor – Eclipse-based Tool Components Architecture allows encapsulation/integration with other verification tools using IBM’s Eclipse Integrated Development Environment Cadena CORBA Component Model verification Next generation of Bandera Java Model- checking Tool Set SpEx JML Verification, etc.

8 Bogor – Domain Specific Model-Checking Extensible modeling language and plug-in architecture allows Bogor to be customized to a variety of application domains Modeling language and Algorithms easily customized to different domains Domain YDomain Z Domain X

9 Variety of Application Domains Hardware Device Drivers Avionics Automotive Telephony GUI

10 Leveraging Domain Knowledge Holzmann developed a customized model extraction from C to Spin Translation using pattern matching of particular domain idioms In essence, an abstract machine for a particular domain Very effective at finding subtle defects Lucent Path Star Telephone Switch Lucent Path Star Telephone Switch

11 Model Checker Variety of System Descriptions Design Notations Byte code State Machines Source code Different levels of abstraction!

12 Abstract machine tailored to domain and level of abstraction The Goal Model-checking Engine Avionics State Machines Domain & Abstraction Extensions

13 Abstract machine tailored to domain and level of abstraction The Goal Model-checking Engine Domain & Abstraction Extensions Device Drivers Source code Domain & Abstraction Extensions

14 Abstract machine tailored to domain and level of abstraction The Goal Model-checking Engine Domain & Abstraction Extensions Domain & Abstraction Extensions Automotive Design Notations Domain & Abstraction Extensions

15 Domain-Specific Model-Checking Bogor -- Extensible Modeling Language Core Modeling Language Threads, Objects, Methods, Exceptions, etc. + Extensions Sets Queues Tables RT CORBA Event Service API Abstraction Domain-specific Abstractions + Real-time Scheduling Quasi-cyclic Search Partial State Representation Bogor -- Customizable Checking Engine Modules Scheduling Strategy State-space Exploration State-space Representation Core Checker Modules Customized Checker Modules …existing modules…

16 Outline of Talk moving beyond assertions & temporal logic SpEx – checking JML specifications Adding support for concurrency to JML avionics mission-control domain model-checking engine for Cadena environment for CORBA Component Model development extension abstracts real-time CORBA event-channel layer II. Checking strong specs for OO programs III. A complex Bogor extension I. A simple Bogor extension a simple version of symmetric sets

17 Modeling Language Extensions Bogor allows definitions of new abstract types and abstract operations as first-class constructs extension Set for SetModule { typedef type ; expdef Set.type create (‘a...); expdef ‘a choose (Set.type ); actiondef add (Set.type, ‘a); expdef boolean forAll(‘a -> boolean, Set.type ); } A new type to represent polymorphic symmetric sets

18 Modeling Language Extensions Bogor allows definitions of new abstract types and abstract operations as first-class constructs extension Set for SetModule { typedef type ; expdef Set.type create (‘a...); expdef ‘a choose (Set.type ); actiondef add (Set.type, ‘a); expdef boolean forAll(‘a -> boolean, Set.type ); } Variable arity function for creating symmetric sets

19 Modeling Language Extensions Bogor allows definitions of new abstract types and abstract operations as first-class constructs extension Set for SetModule { typedef type ; expdef Set.type create (‘a...); expdef ‘a choose (Set.type ); actiondef add (Set.type, ‘a); expdef boolean forAll(‘a -> boolean, Set.type ); } Non-deterministically pick an element of the set to return

20 Modeling Language Extensions Bogor allows definitions of new abstract types and abstract operations as first-class constructs extension Set for SetModule { typedef type ; expdef Set.type create (‘a...); expdef ‘a choose (Set.type ); actiondef add (Set.type, ‘a); expdef boolean forAll(‘a -> boolean, Set.type ); } Higher-order function implements quantification over set elements Predicate on set element Set value to interate over

21 Java methods implementing actions and expressions Extension Implementation Extensions are implemented by associating each item in extension interface with Java methods that provide the semantics for the item (or state-vector storage representation in case of state). extension Set for SetModule { typedef type ; expdef Set.type create (‘a...); expdef ‘a choose (Set.type ); actiondef add (Set.type, ‘a); expdef boolean forAll(‘a -> boolean, Set.type ); } extension Set for SetModule { typedef type ; expdef Set.type create (‘a...); expdef ‘a choose (Set.type ); actiondef add (Set.type, ‘a); expdef boolean forAll(‘a -> boolean, Set.type ); } Extension Implementation Java implementation of set value and linearized (state-vector) representation.

22 Extension Implementation public class MySet implements INonPrimitiveExtValue { protected HashSet set = new HashSet(); protected boolean isNonPrimitiveElement; public void add(IValue v) { set.add(v); } public byte[][] linearize(..., int bitsPerNPV, ObjectIntTable npvIdMap) { Object[] elements = set.toArray(); BitBuffer bb = new BitBuffer(); if (isNonPrimitiveElement) { int[] elementIds = new int[elements.length]; for (int i = 0; i < elements.length; i++) elementIds[i] = npvIdMap.get(elements[i]); Arrays.sort(elementIds); for (int i = 0; i < elements.length; i++) bb.append(elementIds[i], bitsPerNPV); } else... return new byte[][] { bb.toByteArray() }; }... Implementing the set value for the set type

23 Extension Implementation public class MySet implements INonPrimitiveExtValue { protected HashSet set = new HashSet(); protected boolean isNonPrimitiveElement; public void add(IValue v) { set.add(v); } public byte[][] linearize(..., int bitsPerNPV, ObjectIntTable npvIdMap) { Object[] elements = set.toArray(); BitBuffer bb = new BitBuffer(); if (isNonPrimitiveElement) { int[] elementIds = new int[elements.length]; for (int i = 0; i < elements.length; i++) elementIds[i] = npvIdMap.get(elements[i]); Arrays.sort(elementIds); for (int i = 0; i < elements.length; i++) bb.append(elementIds[i], bitsPerNPV); } else... return new byte[][] { bb.toByteArray() }; }... Implementing the set value for the set type Implement Bogor interface for non-primitive value

24 Extension Implementation public class MySet implements INonPrimitiveExtValue { protected HashSet set = new HashSet(); protected boolean isNonPrimitiveElement; public void add(IValue v) { set.add(v); } public byte[][] linearize(..., int bitsPerNPV, ObjectIntTable npvIdMap) { Object[] elements = set.toArray(); BitBuffer bb = new BitBuffer(); if (isNonPrimitiveElement) { int[] elementIds = new int[elements.length]; for (int i = 0; i < elements.length; i++) elementIds[i] = npvIdMap.get(elements[i]); Arrays.sort(elementIds); for (int i = 0; i < elements.length; i++) bb.append(elementIds[i], bitsPerNPV); } else... return new byte[][] { bb.toByteArray() }; }... Implementing the set value for the set type Reuse Java collection to implement set

25 Extension Implementation public class MySet implements INonPrimitiveExtValue { protected HashSet set = new HashSet(); protected boolean isNonPrimitiveElement; public void add(IValue v) { set.add(v); } public byte[][] linearize(..., int bitsPerNPV, ObjectIntTable npvIdMap) { Object[] elements = set.toArray(); BitBuffer bb = new BitBuffer(); if (isNonPrimitiveElement) { int[] elementIds = new int[elements.length]; for (int i = 0; i < elements.length; i++) elementIds[i] = npvIdMap.get(elements[i]); Arrays.sort(elementIds); for (int i = 0; i < elements.length; i++) bb.append(elementIds[i], bitsPerNPV); } else... return new byte[][] { bb.toByteArray() }; }... Implementing the set value for the set type Implementation of add operation

26 Extension Implementation public class MySet implements INonPrimitiveExtValue { protected HashSet set = new HashSet(); protected boolean isNonPrimitiveElement; public void add(IValue v) { set.add(v); } public byte[][] linearize(..., int bitsPerNPV, ObjectIntTable npvIdMap) { Object[] elements = set.toArray(); BitBuffer bb = new BitBuffer(); if (isNonPrimitiveElement) { int[] elementIds = new int[elements.length]; for (int i = 0; i < elements.length; i++) elementIds[i] = npvIdMap.get(elements[i]); Arrays.sort(elementIds); for (int i = 0; i < elements.length; i++) bb.append(elementIds[i], bitsPerNPV); } else... return new byte[][] { bb.toByteArray() }; }... Implementing the set value for the set type Constructs a bit vector that represents the set instead of encoding the HashSet instance Constructs a bit vector that represents the set instead of encoding the HashSet instance See Bogor web site for extensive tutorial (PowerPoint slides) and the paper ”Bogor: An extensible and highly modular software model-checking framework”

27 Outline of Talk avionics mission-control domain model-checking engine for Cadena environment for CORBA Component Model development extension abstracts real-time CORBA event-channel layer III. A complex Bogor extension I. A simple Bogor extension a simple version of symmetric sets moving beyond assertions & temporal logic SpEx – checking JML specifications Adding support for concurrency to JML II. Checking strong specs for OO programs

28 Assertions for Software Verification Use of assertions has become common practice among developers 10 years ago assertions were not considered useful by developers evidence of the effectiveness of assertions David Rosenblum (1995) now some programming languages have included assertions in their standard specifications c.f. Java 1.4 assertions

29 protected synchronized Object extract() { synchronized (head) { Object x = null; LinkedNode first = head.next; if (first != null) { x = first.value; first.value = null; head = first; } return x; } protected void insert(Object x) { synchronized (putLock) { LinkedNode p = new LinkedNode(x); synchronized (last) { last.next = p; last = p; } if (waitingForTake > 0) putLock.notify(); return; } public Object take() { Object x = extract(); if (x != null) return x; else … } public class LinkedNode { public Object value; public LinkedNode next; public LinkedNode(Object x) { value = x; } public class LinkedQueue { protected final Object putLock; protected LinkedNode head; protected LinkedNode last = head; protected int waitingForTake = 0; public LinkedQueue() { putLock = new Object(); head = new LinkedNode(null); } public boolean isEmpty() { synchronized (head) { return head.next == null; } public void put(Object x) { if (x == null) throw new IllegalArgumentException(); insert(x); } protected void insert(Object x) { synchronized (putLock) { LinkedNode p = new LinkedNode(x); synchronized (last) { last.next = p; last = p; } if (waitingForTake > 0) putLock.notify(); return; } Concurrent Queue based on Linked List (Doug Lea’s util.concurrent package) … allows concurrent access to put() and take() assert(x != null);

30 An example public class LinkedNode { public Object value; public LinkedNode next; public LinkedNode(Object x) { value = x; } public class LinkedQueue { protected final Object putLock; protected LinkedNode head; protected LinkedNode last = head; protected int waitingForTake = 0; public LinkedQueue() { putLock = new Object(); head = new LinkedNode(null); } public boolean isEmpty() { synchronized (head) { return head.next == null; } public void put(Object x) { if (x == null) throw new IllegalArgumentException(); insert(x); } protected synchronized Object extract() { synchronized (head) { Object x = null; LinkedNode first = head.next; if (first != null) { x = first.value; first.value = null; head = first; } return x; } protected void insert(Object x) { synchronized (putLock) { LinkedNode p = new LinkedNode(x); synchronized (last) { last.next = p; last = p; } if (waitingForTake > 0) putLock.notify(); return; } public Object take() { Object x = extract(); if (x != null) return x; else … } public class LinkedQueue { protected final Object putLock; protected LinkedNode head; protected LinkedNode last = head; protected int waitingForTake = 0;. Specify that putLock is never null

31 protected synchronized Object extract() { assert(putLock != null); synchronized (head) { Object x = null; LinkedNode first = head.next; if (first != null) { x = first.value; first.value = null; head = first; } return x; } assert(putLock != null); } protected void insert(Object x) { assert(putLock != null); synchronized (putLock) { LinkedNode p = new LinkedNode(x); synchronized (last) { last.next = p; last = p; } if (waitingForTake > 0) putLock.notify(); return; } assert(putLock != null); } public Object take() { assert(putLock != null); Object x = extract(); if (x != null) return x; else … assert(putLock != null); } An example public class LinkedNode { public Object value; public LinkedNode next; public LinkedNode(Object x) { value = x; } public class LinkedQueue { protected final Object putLock; protected LinkedNode head; protected LinkedNode last = head; protected int waitingForTake = 0; public LinkedQueue() { assert(putLock != null); putLock = new Object(); head = new LinkedNode(null); assert(putLock != null); } public boolean isEmpty() { assert(putLock != null); synchronized (head) { return head.next == null; } assert(putLock != null); } public void put(Object x) { assert(putLock != null); if (x == null) throw new IllegalArgumentException(); insert(x); assert(putLock != null); } Specify that putLock is never null Need more declarative formalisms

32 Specification Languages We want specification languages that have a rich set of primitives for observing program state heap-allocated objects, concurrency, etc. make it easy to write useful specifications support lightweight and deep-semantic specifications be checkable using a variety of analysis techniques static analysis, theorem proving, etc.

33 Java Modeling Language (JML) Developed by G. Leavens and other colleagues at Iowa State University very rich set of operators, especially for describing complex heap properties \reach(r), \forall(), \old(), etc. support for specifications with varying degrees of complexity lightweight vs. heavyweight specifications has been checked with a variety of different techniques so far, static analysis, theorem proving and runtime checking Emerging as a standard specification language for Java within the research community

34 Java Modeling Language (JML) public class LinkedNode { public Object value; public LinkedNode next; public LinkedNode(Object x) { value = x; } public class LinkedQueue { protected final Object putLock; protected LinkedNode head; protected LinkedNode last = head; protected int waitingForTake = 0; public LinkedQueue() { putLock = new Object(); head = new LinkedNode(null); } public boolean isEmpty() { synchronized (head) { return head.next == null; } public void put(Object x) { if (x == null) throw new IllegalArgumentException(); insert(x); } protected synchronized Object extract() { synchronized (head) { Object x = null; LinkedNode first = head.next; if (first != null) { x = first.value; first.value = null; head = first; } return x; } protected void insert(Object x) { synchronized (putLock) { LinkedNode p = new LinkedNode(x); synchronized (last) { last.next = p; last = p; } if (waitingForTake > 0) putLock.notify(); return; } public Object take() { Object x = extract(); if (x != null) return x; else … } protected void insert(Object x) { assert(x != null); synchronized (putLock) { LinkedNode p = new LinkedNode(x); synchronized (last) { last.next = p; last = p; } if (waitingForTake > 0) putLock.notify(); return; } //@ requires x != null; protected void insert(Object x) { synchronized (putLock) { LinkedNode p = new LinkedNode(x); synchronized (last) { last.next = p; last = p; } if (waitingForTake > 0) putLock.notify(); return; }

35 protected synchronized Object extract() { assert(putLock != null); synchronized (head) { Object x = null; LinkedNode first = head.next; if (first != null) { x = first.value; first.value = null; head = first; } return x; } assert(putLock != null); } protected void insert(Object x) { assert(putLock != null); synchronized (putLock) { LinkedNode p = new LinkedNode(x); synchronized (last) { last.next = p; last = p; } if (waitingForTake > 0) putLock.notify(); return; } assert(putLock != null); } public Object take() { assert(putLock != null); Object x = extract(); if (x != null) return x; else … assert(putLock != null); } An example public class LinkedNode { public Object value; public LinkedNode next; public LinkedNode(Object x) { value = x; } } public class LinkedQueue { protected final Object putLock; protected LinkedNode head; protected LinkedNode last = head; protected int waitingForTake = 0; public LinkedQueue() { assert(putLock != null); putLock = new Object(); head = new LinkedNode(null); assert(putLock != null); } public boolean isEmpty() { assert(putLock != null); synchronized (head) { return head.next == null; } assert(putLock != null); } public void put(Object x) { assert(putLock != null); if (x == null) throw new IllegalArgumentException(); insert(x); assert(putLock != null); } public class LinkedQueue { protected final /*@ non_null @*/ Object putLock;.

36 public class LinkedNode { public Object value; public LinkedNode next; /*@ behavior @ ensures value == x; @*/ public LinkedNode(Object x) { value = x; } public class LinkedQueue { protected final /*@ non_null @*/ Object putLock; protected /*@ non_null @*/ LinkedNode head; protected /*@ non_null @*/ LinkedNode last = head; protected int waitingForTake = 0; //@ instance invariant waitingForTake >= 0; //@ instance invariant \reach(head).has(last); /*@ behavior @ assignable head, last, putLock, waitingForTake; @ ensures \fresh(head, putLock) && head.next == null; @*/ public LinkedQueue() { putLock = new Object(); head = new LinkedNode(null); } /*@ behavior @ ensures \result head.next == null; @*/ public boolean isEmpty() { synchronized (head) { return head.next == null; } /*@ behavior @ requires n != null; @ assignable last, last.next; @*/ protected void refactoredInsert(LinkedNode n) { last.next = n; last = n; } /*@ behavior @ requires x != null; @ ensures true; @ also behavior @ requires x == null; @ signals (Exception e) e instanceof IllegalArgumentException; @*/ public void put(Object x) { if (x == null) throw new IllegalArgumentException(); insert(x); } protected synchronized Object extract() { synchronized (head) { return refactoredExtract(); } /*@ behavior @ assignable head, head.next.value; @ ensures \result == null || (\exists LinkedNode n; @ \old(\reach(head)).has(n); @ n.value == \result @ && !(\reach(head).has(n))); @*/ protected Object refactoredExtract() { Object x = null; LinkedNode first = head.next; if (first != null) { x = first.value; first.value = null; head = first; } return x; } /*@ behavior @ requires x != null; @ ensures last.value == x && \fresh(last); @*/ protected void insert(Object x) { synchronized (putLock) { LinkedNode p = new LinkedNode(x); synchronized (last) refactoredInsert(p); if (waitingForTake > 0) putLock.notify(); return; } Java Modeling Language (JML) … ability to make deep-semantic specifications /*@ behavior @ assignable head, head.next.value; @ ensures \result == null || (\exists LinkedNode n; @ \old(\reach(head)).has(n); @ n.value == \result @ && !(\reach(head).has(n))); @*/ protected synchronized Object extract() { synchronized(head) { Object x = null; LinkedNode first = head.next; if (first != null) { x = first.value; first.value = null; head = first; } return x; }

37 public class LinkedNode { public Object value; public LinkedNode next; /*@ behavior @ ensures value == x; @*/ public LinkedNode(Object x) { value = x; } public class LinkedQueue { protected final /*@ non_null @*/ Object putLock; protected /*@ non_null @*/ LinkedNode head; protected /*@ non_null @*/ LinkedNode last = head; protected int waitingForTake = 0; //@ instance invariant waitingForTake >= 0; //@ instance invariant \reach(head).has(last); /*@ behavior @ assignable head, last, putLock, waitingForTake; @ ensures \fresh(head, putLock) && head.next == null; @*/ public LinkedQueue() { putLock = new Object(); head = new LinkedNode(null); } /*@ behavior @ ensures \result head.next == null; @*/ public boolean isEmpty() { synchronized (head) { return head.next == null; } /*@ behavior @ requires n != null; @ assignable last, last.next; @*/ protected void refactoredInsert(LinkedNode n) { last.next = n; last = n; } /*@ behavior @ requires x != null; @ ensures true; @ also behavior @ requires x == null; @ signals (Exception e) e instanceof IllegalArgumentException; @*/ public void put(Object x) { if (x == null) throw new IllegalArgumentException(); insert(x); } protected synchronized Object extract() { synchronized (head) { return refactoredExtract(); } /*@ behavior @ assignable head, head.next.value; @ ensures \result == null || (\exists LinkedNode n; @ \old(\reach(head)).has(n); @ n.value == \result @ && !(\reach(head).has(n))); @*/ protected Object refactoredExtract() { Object x = null; LinkedNode first = head.next; if (first != null) { x = first.value; first.value = null; head = first; } return x; } /*@ behavior @ requires x != null; @ ensures last.value == x && \fresh(last); @*/ protected void insert(Object x) { synchronized (putLock) { LinkedNode p = new LinkedNode(x); synchronized (last) refactoredInsert(p); if (waitingForTake > 0) putLock.notify(); return; } Java Modeling Language (JML) … ability to make deep-semantic specifications /*@ behavior @ assignable head, head.next.value; @ ensures \result == null || (\exists LinkedNode n; @ \old(\reach(head)).has(n); @ n.value == \result @ && !(\reach(head).has(n))); @*/ protected synchronized Object extract() { synchronized(head) { Object x = null; LinkedNode first = head.next; if (first != null) { x = first.value; first.value = null; head = first; } return x; } Frame conditions – can only assign to these variables.

38 public class LinkedNode { public Object value; public LinkedNode next; /*@ behavior @ ensures value == x; @*/ public LinkedNode(Object x) { value = x; } public class LinkedQueue { protected final /*@ non_null @*/ Object putLock; protected /*@ non_null @*/ LinkedNode head; protected /*@ non_null @*/ LinkedNode last = head; protected int waitingForTake = 0; //@ instance invariant waitingForTake >= 0; //@ instance invariant \reach(head).has(last); /*@ behavior @ assignable head, last, putLock, waitingForTake; @ ensures \fresh(head, putLock) && head.next == null; @*/ public LinkedQueue() { putLock = new Object(); head = new LinkedNode(null); } /*@ behavior @ ensures \result head.next == null; @*/ public boolean isEmpty() { synchronized (head) { return head.next == null; } /*@ behavior @ requires n != null; @ assignable last, last.next; @*/ protected void refactoredInsert(LinkedNode n) { last.next = n; last = n; } /*@ behavior @ requires x != null; @ ensures true; @ also behavior @ requires x == null; @ signals (Exception e) e instanceof IllegalArgumentException; @*/ public void put(Object x) { if (x == null) throw new IllegalArgumentException(); insert(x); } protected synchronized Object extract() { synchronized (head) { return refactoredExtract(); } /*@ behavior @ assignable head, head.next.value; @ ensures \result == null || (\exists LinkedNode n; @ \old(\reach(head)).has(n); @ n.value == \result @ && !(\reach(head).has(n))); @*/ protected Object refactoredExtract() { Object x = null; LinkedNode first = head.next; if (first != null) { x = first.value; first.value = null; head = first; } return x; } /*@ behavior @ requires x != null; @ ensures last.value == x && \fresh(last); @*/ protected void insert(Object x) { synchronized (putLock) { LinkedNode p = new LinkedNode(x); synchronized (last) refactoredInsert(p); if (waitingForTake > 0) putLock.notify(); return; } Java Modeling Language (JML) … ability to make deep-semantic specifications /*@ behavior @ assignable head, head.next.value; @ ensures \result == null || (\exists LinkedNode n; @ \old(\reach(head)).has(n); @ n.value == \result @ && !(\reach(head).has(n))); @*/ protected synchronized Object extract() { synchronized(head) { Object x = null; LinkedNode first = head.next; if (first != null) { x = first.value; first.value = null; head = first; } return x; } Post condition – the result of the method is null, or…

39 public class LinkedNode { public Object value; public LinkedNode next; /*@ behavior @ ensures value == x; @*/ public LinkedNode(Object x) { value = x; } public class LinkedQueue { protected final /*@ non_null @*/ Object putLock; protected /*@ non_null @*/ LinkedNode head; protected /*@ non_null @*/ LinkedNode last = head; protected int waitingForTake = 0; //@ instance invariant waitingForTake >= 0; //@ instance invariant \reach(head).has(last); /*@ behavior @ assignable head, last, putLock, waitingForTake; @ ensures \fresh(head, putLock) && head.next == null; @*/ public LinkedQueue() { putLock = new Object(); head = new LinkedNode(null); } /*@ behavior @ ensures \result head.next == null; @*/ public boolean isEmpty() { synchronized (head) { return head.next == null; } /*@ behavior @ requires n != null; @ assignable last, last.next; @*/ protected void refactoredInsert(LinkedNode n) { last.next = n; last = n; } /*@ behavior @ requires x != null; @ ensures true; @ also behavior @ requires x == null; @ signals (Exception e) e instanceof IllegalArgumentException; @*/ public void put(Object x) { if (x == null) throw new IllegalArgumentException(); insert(x); } protected synchronized Object extract() { synchronized (head) { return refactoredExtract(); } /*@ behavior @ assignable head, head.next.value; @ ensures \result == null || (\exists LinkedNode n; @ \old(\reach(head)).has(n); @ n.value == \result @ && !(\reach(head).has(n))); @*/ protected Object refactoredExtract() { Object x = null; LinkedNode first = head.next; if (first != null) { x = first.value; first.value = null; head = first; } return x; } /*@ behavior @ requires x != null; @ ensures last.value == x && \fresh(last); @*/ protected void insert(Object x) { synchronized (putLock) { LinkedNode p = new LinkedNode(x); synchronized (last) refactoredInsert(p); if (waitingForTake > 0) putLock.notify(); return; } Java Modeling Language (JML) … ability to make deep-semantic specifications /*@ behavior @ assignable head, head.next.value; @ ensures \result == null || (\exists LinkedNode n; @ \old(\reach(head)).has(n); @ n.value == \result @ && !(\reach(head).has(n))); @*/ protected synchronized Object extract() { synchronized(head) { Object x = null; LinkedNode first = head.next; if (first != null) { x = first.value; first.value = null; head = first; } return x; } there exists an instance n of the class LinkedNode (existential quantification of heap data) there exists an instance n of the class LinkedNode (existential quantification of heap data)

40 public class LinkedNode { public Object value; public LinkedNode next; /*@ behavior @ ensures value == x; @*/ public LinkedNode(Object x) { value = x; } public class LinkedQueue { protected final /*@ non_null @*/ Object putLock; protected /*@ non_null @*/ LinkedNode head; protected /*@ non_null @*/ LinkedNode last = head; protected int waitingForTake = 0; //@ instance invariant waitingForTake >= 0; //@ instance invariant \reach(head).has(last); /*@ behavior @ assignable head, last, putLock, waitingForTake; @ ensures \fresh(head, putLock) && head.next == null; @*/ public LinkedQueue() { putLock = new Object(); head = new LinkedNode(null); } /*@ behavior @ ensures \result head.next == null; @*/ public boolean isEmpty() { synchronized (head) { return head.next == null; } /*@ behavior @ requires n != null; @ assignable last, last.next; @*/ protected void refactoredInsert(LinkedNode n) { last.next = n; last = n; } /*@ behavior @ requires x != null; @ ensures true; @ also behavior @ requires x == null; @ signals (Exception e) e instanceof IllegalArgumentException; @*/ public void put(Object x) { if (x == null) throw new IllegalArgumentException(); insert(x); } protected synchronized Object extract() { synchronized (head) { return refactoredExtract(); } /*@ behavior @ assignable head, head.next.value; @ ensures \result == null || (\exists LinkedNode n; @ \old(\reach(head)).has(n); @ n.value == \result @ && !(\reach(head).has(n))); @*/ protected Object refactoredExtract() { Object x = null; LinkedNode first = head.next; if (first != null) { x = first.value; first.value = null; head = first; } return x; } /*@ behavior @ requires x != null; @ ensures last.value == x && \fresh(last); @*/ protected void insert(Object x) { synchronized (putLock) { LinkedNode p = new LinkedNode(x); synchronized (last) refactoredInsert(p); if (waitingForTake > 0) putLock.notify(); return; } Java Modeling Language (JML) … ability to make deep-semantic specifications /*@ behavior @ assignable head, head.next.value; @ ensures \result == null || (\exists LinkedNode n; @ \old(\reach(head)).has(n); @ n.value == \result @ && !(\reach(head).has(n))); @*/ protected synchronized Object extract() { synchronized(head) { Object x = null; LinkedNode first = head.next; if (first != null) { x = first.value; first.value = null; head = first; } return x; } look at the “pre-state” – the state of the execution when the method was entered

41 public class LinkedNode { public Object value; public LinkedNode next; /*@ behavior @ ensures value == x; @*/ public LinkedNode(Object x) { value = x; } public class LinkedQueue { protected final /*@ non_null @*/ Object putLock; protected /*@ non_null @*/ LinkedNode head; protected /*@ non_null @*/ LinkedNode last = head; protected int waitingForTake = 0; //@ instance invariant waitingForTake >= 0; //@ instance invariant \reach(head).has(last); /*@ behavior @ assignable head, last, putLock, waitingForTake; @ ensures \fresh(head, putLock) && head.next == null; @*/ public LinkedQueue() { putLock = new Object(); head = new LinkedNode(null); } /*@ behavior @ ensures \result head.next == null; @*/ public boolean isEmpty() { synchronized (head) { return head.next == null; } /*@ behavior @ requires n != null; @ assignable last, last.next; @*/ protected void refactoredInsert(LinkedNode n) { last.next = n; last = n; } /*@ behavior @ requires x != null; @ ensures true; @ also behavior @ requires x == null; @ signals (Exception e) e instanceof IllegalArgumentException; @*/ public void put(Object x) { if (x == null) throw new IllegalArgumentException(); insert(x); } protected synchronized Object extract() { synchronized (head) { return refactoredExtract(); } /*@ behavior @ assignable head, head.next.value; @ ensures \result == null || (\exists LinkedNode n; @ \old(\reach(head)).has(n); @ n.value == \result @ && !(\reach(head).has(n))); @*/ protected Object refactoredExtract() { Object x = null; LinkedNode first = head.next; if (first != null) { x = first.value; first.value = null; head = first; } return x; } /*@ behavior @ requires x != null; @ ensures last.value == x && \fresh(last); @*/ protected void insert(Object x) { synchronized (putLock) { LinkedNode p = new LinkedNode(x); synchronized (last) refactoredInsert(p); if (waitingForTake > 0) putLock.notify(); return; } Java Modeling Language (JML) … ability to make deep-semantic specifications /*@ behavior @ assignable head, head.next.value; @ ensures \result == null || (\exists LinkedNode n; @ \old(\reach(head)).has(n); @ n.value == \result @ && !(\reach(head).has(n))); @*/ protected synchronized Object extract() { synchronized(head) { Object x = null; LinkedNode first = head.next; if (first != null) { x = first.value; first.value = null; head = first; } return x; } in the pre-state, form the set of objects that are reachable via object references from head field

42 public class LinkedNode { public Object value; public LinkedNode next; /*@ behavior @ ensures value == x; @*/ public LinkedNode(Object x) { value = x; } public class LinkedQueue { protected final /*@ non_null @*/ Object putLock; protected /*@ non_null @*/ LinkedNode head; protected /*@ non_null @*/ LinkedNode last = head; protected int waitingForTake = 0; //@ instance invariant waitingForTake >= 0; //@ instance invariant \reach(head).has(last); /*@ behavior @ assignable head, last, putLock, waitingForTake; @ ensures \fresh(head, putLock) && head.next == null; @*/ public LinkedQueue() { putLock = new Object(); head = new LinkedNode(null); } /*@ behavior @ ensures \result head.next == null; @*/ public boolean isEmpty() { synchronized (head) { return head.next == null; } /*@ behavior @ requires n != null; @ assignable last, last.next; @*/ protected void refactoredInsert(LinkedNode n) { last.next = n; last = n; } /*@ behavior @ requires x != null; @ ensures true; @ also behavior @ requires x == null; @ signals (Exception e) e instanceof IllegalArgumentException; @*/ public void put(Object x) { if (x == null) throw new IllegalArgumentException(); insert(x); } protected synchronized Object extract() { synchronized (head) { return refactoredExtract(); } /*@ behavior @ assignable head, head.next.value; @ ensures \result == null || (\exists LinkedNode n; @ \old(\reach(head)).has(n); @ n.value == \result @ && !(\reach(head).has(n))); @*/ protected Object refactoredExtract() { Object x = null; LinkedNode first = head.next; if (first != null) { x = first.value; first.value = null; head = first; } return x; } /*@ behavior @ requires x != null; @ ensures last.value == x && \fresh(last); @*/ protected void insert(Object x) { synchronized (putLock) { LinkedNode p = new LinkedNode(x); synchronized (last) refactoredInsert(p); if (waitingForTake > 0) putLock.notify(); return; } Java Modeling Language (JML) … ability to make deep-semantic specifications /*@ behavior @ assignable head, head.next.value; @ ensures \result == null || (\exists LinkedNode n; @ \old(\reach(head)).has(n); @ n.value == \result @ && !(\reach(head).has(n))); @*/ protected synchronized Object extract() { synchronized(head) { Object x = null; LinkedNode first = head.next; if (first != null) { x = first.value; first.value = null; head = first; } return x; } the set of objects reachable from head in the pre-state has n in it (i.e., n is a member of the set)

43 public class LinkedNode { public Object value; public LinkedNode next; /*@ behavior @ ensures value == x; @*/ public LinkedNode(Object x) { value = x; } public class LinkedQueue { protected final /*@ non_null @*/ Object putLock; protected /*@ non_null @*/ LinkedNode head; protected /*@ non_null @*/ LinkedNode last = head; protected int waitingForTake = 0; //@ instance invariant waitingForTake >= 0; //@ instance invariant \reach(head).has(last); /*@ behavior @ assignable head, last, putLock, waitingForTake; @ ensures \fresh(head, putLock) && head.next == null; @*/ public LinkedQueue() { putLock = new Object(); head = new LinkedNode(null); } /*@ behavior @ ensures \result head.next == null; @*/ public boolean isEmpty() { synchronized (head) { return head.next == null; } /*@ behavior @ requires n != null; @ assignable last, last.next; @*/ protected void refactoredInsert(LinkedNode n) { last.next = n; last = n; } /*@ behavior @ requires x != null; @ ensures true; @ also behavior @ requires x == null; @ signals (Exception e) e instanceof IllegalArgumentException; @*/ public void put(Object x) { if (x == null) throw new IllegalArgumentException(); insert(x); } protected synchronized Object extract() { synchronized (head) { return refactoredExtract(); } /*@ behavior @ assignable head, head.next.value; @ ensures \result == null || (\exists LinkedNode n; @ \old(\reach(head)).has(n); @ n.value == \result @ && !(\reach(head).has(n))); @*/ protected Object refactoredExtract() { Object x = null; LinkedNode first = head.next; if (first != null) { x = first.value; first.value = null; head = first; } return x; } /*@ behavior @ requires x != null; @ ensures last.value == x && \fresh(last); @*/ protected void insert(Object x) { synchronized (putLock) { LinkedNode p = new LinkedNode(x); synchronized (last) refactoredInsert(p); if (waitingForTake > 0) putLock.notify(); return; } Java Modeling Language (JML) … ability to make deep-semantic specifications /*@ behavior @ assignable head, head.next.value; @ ensures \result == null || (\exists LinkedNode n; @ \old(\reach(head)).has(n); @ n.value == \result @ && !(\reach(head).has(n))); @*/ protected synchronized Object extract() { synchronized(head) { Object x = null; LinkedNode first = head.next; if (first != null) { x = first.value; first.value = null; head = first; } return x; } the value in the n node matches the method result

44 public class LinkedNode { public Object value; public LinkedNode next; /*@ behavior @ ensures value == x; @*/ public LinkedNode(Object x) { value = x; } public class LinkedQueue { protected final /*@ non_null @*/ Object putLock; protected /*@ non_null @*/ LinkedNode head; protected /*@ non_null @*/ LinkedNode last = head; protected int waitingForTake = 0; //@ instance invariant waitingForTake >= 0; //@ instance invariant \reach(head).has(last); /*@ behavior @ assignable head, last, putLock, waitingForTake; @ ensures \fresh(head, putLock) && head.next == null; @*/ public LinkedQueue() { putLock = new Object(); head = new LinkedNode(null); } /*@ behavior @ ensures \result head.next == null; @*/ public boolean isEmpty() { synchronized (head) { return head.next == null; } /*@ behavior @ requires n != null; @ assignable last, last.next; @*/ protected void refactoredInsert(LinkedNode n) { last.next = n; last = n; } /*@ behavior @ requires x != null; @ ensures true; @ also behavior @ requires x == null; @ signals (Exception e) e instanceof IllegalArgumentException; @*/ public void put(Object x) { if (x == null) throw new IllegalArgumentException(); insert(x); } protected synchronized Object extract() { synchronized (head) { return refactoredExtract(); } /*@ behavior @ assignable head, head.next.value; @ ensures \result == null || (\exists LinkedNode n; @ \old(\reach(head)).has(n); @ n.value == \result @ && !(\reach(head).has(n))); @*/ protected Object refactoredExtract() { Object x = null; LinkedNode first = head.next; if (first != null) { x = first.value; first.value = null; head = first; } return x; } /*@ behavior @ requires x != null; @ ensures last.value == x && \fresh(last); @*/ protected void insert(Object x) { synchronized (putLock) { LinkedNode p = new LinkedNode(x); synchronized (last) refactoredInsert(p); if (waitingForTake > 0) putLock.notify(); return; } Java Modeling Language (JML) … ability to make deep-semantic specifications /*@ behavior @ assignable head, head.next.value; @ ensures \result == null || (\exists LinkedNode n; @ \old(\reach(head)).has(n); @ n.value == \result @ && !(\reach(head).has(n))); @*/ protected synchronized Object extract() { synchronized(head) { Object x = null; LinkedNode first = head.next; if (first != null) { x = first.value; first.value = null; head = first; } return x; } the set of objects reachable from head in the final state does not have n in it.

45 Bogor Specs like this haven’t been checked with model-checking before… What makes Bogor well-suited for checking JML? Can we check JML efficiently? Questions…

46 Bogor’s Heap Representation Key Points… …explicit heap representation State …transition may create new objects, garbage, etc. Heap …garbage is eliminated …precise heap model …after each transition, a topological sort gives heap objects a canonical order Canonical heap …sort walks over heap, canonicalizes, and collects info …precise alias information …have access to all visited states (but, efficiently stored using collapse compression)

47 Bogor’s Heap Representation — Enables JML Specs Check Key Points… … many JML features are easy to support in Bogor State …transition may create new objects, garbage, etc. Heap …can easily compare objects in methods pre/post-states (c.f., \old) …precise alias information (c.f., assignable) Canonical heap …sort walks over heap, canonicalizes, and collects info …precise heap model (c.f., \reach)

48 Assessment The ability to state strong properties of heap- allocated data (as JML enables) is very useful complementary to techniques developed by UPenn team (JIST) which focus on synthesizing ordering constraints on calls to Java interfaces Bogor’s native support for OO features, explicit- state representation and extension facility enable JML property checking to be implemented fairly easily Bogor’s sophisticated partial-order reduction strategies (rely on dynamic escape and lock- pattern analysis) enable checking to be carried out efficiently for software units.

49 JML Reasoning Tools and Technologies JMLc/Testing Theorem Proving … m(…) { assume pre-conditions … … … … … … prove post-conditions } … m(…) { } Environment manipulate formulas checking that specifications are satisfied for particular traces generated by the environment (test harness) checking that specifications are satisfied for particular traces generated by the environment (test harness) SPeX/Bogor (!)

50 Experiments without reductions w/ JML w/o JML Test Platform JDK 1.4.1 (32-bit mode) on a 2 GHz Opteron with maximum heap of 1 GB running Linux (64-bit mode) Checking JML specs adds 20-40% overhead A bad case… 300%

51 Bogor’s Reduction Algorithms — Enables Checking JML Specs Indicates little overhead compared with simply exploring the state-space w/ JML w/o JML w/ JML w/o JML w/ POR w/o POR 8 hrs  1.5 mins

52 Tool Development Framework Bogor – Eclipse-based Tool Components Architecture allows encapsulation/integration with other verification tools using IBM’s Eclipse Integrated Development Environment Cadena CORBA Component Model verification Next generation of Bandera Java Model- checking Tool Set SpEx JML Verification, etc.

53 JMLEclipse JML syntax highlighting JML well-formedness checking Working with a number of groups in JML community to integrate static analysis and theorem-proving based tools into a single framework.

54 Outline of Talk avionics mission-control domain model-checking engine for Cadena environment for CORBA Component Model development extension abstracts real-time CORBA event-channel layer III. A complex Bogor extension I. A simple Bogor extension a simple version of symmetric sets moving beyond assertions & temporal logic SpEx – checking JML specifications Adding support for concurrency to JML II. Checking strong specs for OO programs


Download ppt "Bogor Support US Army Research Office (ARO) US National Science Foundation (NSF) US Department of Defense Advanced Research Projects Agency (DARPA) Rockwell-Collins."

Similar presentations


Ads by Google