Permissive Interfaces Tom Henzinger Ranjit Jhala Rupak Majumdar.

Slides:



Advertisements
Similar presentations
Interface Theories With Component Reuse Laurent DoyenEPFL Thomas HenzingerEPFL Barbara JobstmannEPFL Tatjana PetrovEPFL.
Advertisements

Verification of Evolving Software Natasha Sharygina Joint work with Sagar Chaki and Nishant Sinha Carnegie Mellon University.
Abstraction and Modular Reasoning for the Verification of Software Corina Pasareanu NASA Ames Research Center.
Rigorous Software Development CSCI-GA Instructor: Thomas Wies Spring 2012 Lecture 13.
Introducing BLAST Software Verification John Gallagher CS4117.
A survey of techniques for precise program slicing Komondoor V. Raghavan Indian Institute of Science, Bangalore.
BLAST-A Model Checker for C Developed by Thomas A. Henzinger (EPFL) Rupak Majumdar (UC Los Angeles) Ranjit Jhala (UC San Diego) Dirk Beyer (Simon Fraser.
The Software Model Checker BLAST by Dirk Beyer, Thomas A. Henzinger, Ranjit Jhala and Rupak Majumdar Presented by Yunho Kim Provable Software Lab, KAIST.
The number of edge-disjoint transitive triples in a tournament.
Thread-modular Abstraction Refinement Tom Henzinger Ranjit Jhala Rupak Majumdar Shaz Qadeer.
Termination Proofs for Systems Code Andrey Rybalchenko, EPFL/MPI joint work with Byron Cook, MSR and Andreas Podelski, MPI PLDI’2006, Ottawa.
Convertibility Verification and Converter Synthesis: Two Faces of the Same Coin Jie-Hong Jiang EE249 Discussion 11/21/2002 Passerone et al., ICCAD ’ 02.
STARI: A Case Study in Compositional and Hierarchical Timing Verification Serdar Tasiran, Prof. Robert K. Brayton Department of Electrical Engineering.
Lazy Abstraction Thomas A. Henzinger Ranjit Jhala Rupak Majumdar Grégoire Sutre UC Berkeley.
Establishing Local Temporal Heap Safety Properties with Applications to Compile-Time Memory Management Ran Shaham Eran Yahav Elliot Kolodner Mooly Sagiv.
Thread-modular Abstraction Refinement Tom Henzinger Ranjit Jhala Rupak Majumdar [UC Berkeley] Shaz Qadeer [Microsoft Research]
Using Interfaces to Analyze Compositionality Haiyang Zheng and Rachel Zhou EE290N Class Project Presentation Dec. 10, 2004.
Speeding Up Dataflow Analysis Using Flow- Insensitive Pointer Analysis Stephen Adams, Tom Ball, Manuvir Das Sorin Lerner, Mark Seigle Westley Weimer Microsoft.
Modular Verification of Multithreaded Software Shaz Qadeer Compaq Systems Research Center Shaz Qadeer Compaq Systems Research Center Joint work with Cormac.
Counter Example Guided Refinement CEGAR Mooly Sagiv.
Automatically Validating Temporal Safety Properties of Interfaces Thomas Ball and Sriram K. Rajamani Software Productivity Tools, Microsoft Research Presented.
Race Checking by Context Inference Tom Henzinger Ranjit Jhala Rupak Majumdar UC Berkeley.
DART Directed Automated Random Testing Patrice Godefroid, Nils Klarlund, and Koushik Sen Syed Nabeel.
Houdini: An Annotation Assistant for ESC/Java Cormac Flanagan and K. Rustan M. Leino Compaq Systems Research Center.
Software Reliability Methods Sorin Lerner. Software reliability methods: issues What are the issues?
Synthesis of Interface Specifications for Java Classes Rajeev Alur University of Pennsylvania Joint work with P. Cerny, G. Gupta, P. Madhusudan, W. Nam,
Temporal-Safety Proofs for Systems Code Thomas A. Henzinger Ranjit Jhala Rupak Majumdar George Necula Westley Weimer Grégoire Sutre UC Berkeley.
Overview of program analysis Mooly Sagiv html://
Path Slicing Presentation by Massimiliano Menarini Ranjit Jhala and Rupak Majumdar, “Path Slicing” PLDI 05 (June 2005, Chicago, Illinois)
Lazy Abstraction Tom Henzinger Ranjit Jhala Rupak Majumdar Grégoire Sutre.
Program Analysis Mooly Sagiv Tel Aviv University Sunday Scrieber 8 Monday Schrieber.
Ranjit Jhala Rupak Majumdar Interprocedural Analysis of Asynchronous Programs.
Lazy Abstraction Lecture 3 : Partial Analysis Ranjit Jhala UC San Diego With: Tom Henzinger, Rupak Majumdar, Ken McMillan, Gregoire Sutre.
Thread-modular Abstraction Refinement Thomas A. Henzinger, et al. CAV 2003 Seonggun Kim KAIST CS750b.
Software Testing Sudipto Ghosh CS 406 Fall 99 November 9, 1999.
CSC2108 Lazy Abstraction on Software Model Checking Wai Sum Mong.
Automatic Abstraction Refinement for GSTE Yan Chen, Yujing He, and Fei Xie Portland State University Jin Yang Intel Nov 13, 2007.
By: Pashootan Vaezipoor Path Invariant Simon Fraser University – Spring 09.
Program Analysis with Dynamic Change of Precision Dirk Beyer Tom Henzinger Grégory Théoduloz Presented by: Pashootan Vaezipoor Directed Reading ASE 2008.
Refinement Type Inference via Horn Constraint Optimization Kodai Hashimoto and Hiroshi Unno (University of Tsukuba, Japan)
Rule Checking SLAM Checking Temporal Properties of Software with Boolean Programs Thomas Ball, Sriram K. Rajamani Microsoft Research Presented by Okan.
Inferring Specifications to Detect Errors in Code Mana Taghdiri Presented by: Robert Seater MIT Computer Science & AI Lab.
Race Checking by Context Inference Tom Henzinger Ranjit Jhala Rupak Majumdar UC Berkeley.
On Reducing the Global State Graph for Verification of Distributed Computations Vijay K. Garg, Arindam Chakraborty Parallel and Distributed Systems Laboratory.
Type Systems CS Definitions Program analysis Discovering facts about programs. Dynamic analysis Program analysis by using program executions.
Lazy Abstraction Jinseong Jeon ARCS, KAIST CS750b, KAIST2/26 References Lazy Abstraction –Thomas A. Henzinger et al., POPL ’02 Software verification.
Program Analysis and Verification Spring 2015 Program Analysis and Verification Lecture 12: Abstract Interpretation IV Roman Manevich Ben-Gurion University.
Learning Symbolic Interfaces of Software Components Zvonimir Rakamarić.
CSC 480 Software Engineering Testing - I. Plan project Integrate & test system Analyze requirements Design Maintain Test units Implement Software Engineering.
Lecture 5 1 CSP tools for verification of Sec Prot Overview of the lecture The Casper interface Refinement checking and FDR Model checking Theorem proving.
Reducing Combinatorics in Testing Product Lines Chang Hwan Peter Kim, Don Batory, and Sarfraz Khurshid University of Texas at Austin.
The Yogi Project Software property checking via static analysis and testing Aditya V. Nori, Sriram K. Rajamani, Sai Deep Tetali, Aditya V. Thakur Microsoft.
Open Incremental Model Checking (OIMC) and the Role of Contracts Model-Based Programming and Verification.
Software Construction Lecture 19 Software Testing-2.
Static Timing Analysis
Ranjit Jhala Rupak Majumdar Interprocedural Analysis of Asynchronous Programs.
/ PSWLAB Evidence-Based Analysis and Inferring Preconditions for Bug Detection By D. Brand, M. Buss, V. C. Sreedhar published in ICSM 2007.
Random Test Generation of Unit Tests: Randoop Experience
Rely: Verifying Quantitative Reliability for Programs that Execute on Unreliable Hardware Michael Carbin, Sasa Misailovic, and Martin Rinard MIT CSAIL.
Approximation Algorithms based on linear programming.
The software model checker BLAST Dirk Beyer, Thomas A. Henzinger, Ranjit Jhala, Rupak Majumdar Presented by Yunho Kim TexPoint fonts used in EMF. Read.
Presentation Title 2/4/2018 Software Verification using Predicate Abstraction and Iterative Refinement: Part Bug Catching: Automated Program Verification.
A Review of Software Testing - P. David Coward
Textbook: Principles of Program Analysis
자바 언어를 위한 정적 분석 (Static Analyses for Java) ‘99 한국정보과학회 가을학술발표회 튜토리얼
Abstractions from Proofs
Abstraction, Verification & Refinement
Predicate Abstraction
Model Checking and Its Applications
BLAST: A Software Verification Tool for C programs
Presentation transcript:

Permissive Interfaces Tom Henzinger Ranjit Jhala Rupak Majumdar

A Problem with Program Analysis Whole Program Analysis not always possible Availability: Client code missing Scalability: Whole system too large Client Library

Modular Program Analysis Find interface for Library Use interface to verify client Client Library

Modular Program Analysis Availability: Interface independent of Client Scalability: Interface small, abstraction of Library Library Interface

What is an Interface ? Interface : Constraints on legal uses of API API Calls after which library is in a legal state Library LegalError Interface Library StatesAPI

Library LegalError Example Legal e=0 Error e!=0 Library StatesInterfaceAPI n0n0 n1n1 acq rel n2n2 acq read rel Safe: Interface µ Legal Call Sequences Static e=0; Static a=NULL; Static e=0; Static a=NULL; acq(){ if(a==NULL){ a:= m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:= m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:= m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:= m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;}

n0n0 n1n1 acq / x rel / x n2n2 acq / x write read write read rel / x n0n0 n1n1 acq rel n2n2 acq read rel Safety Not Enough! InterfaceAPI Disallows calls to write Useless for Modular Program Analysis Static e=0, a=NULL, x=0; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;} acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;} write(){ if(x!=0){ m_wr(a); } else e:=1; return;} write(){ if(x!=0){ m_wr(a); } else e:=1; return;} relx(){ a:=NULL; x:=0;} relx(){ a:=NULL; x:=0;}

Permissive Interfaces InterfaceAPI n0n0 n1n1 acq n3n3 read rel/x Permissive: Legal Call Sequences µ Interface Modular Analysis: Safe + Permissive Interfaces Static e=0, a=NULL, x=0; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;} acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;} write(){ if(x!=0){ m_wr(a); } else e:=1; return;} write(){ if(x!=0){ m_wr(a); } else e:=1; return;} relx(){ a:=NULL; x:=0;} relx(){ a:=NULL; x:=0;} n2n2 acqx relx write read

Plan 1. Motivation 2. Characterizing Safe, Permissive Interfaces 3. Computing Safe, Permissive Interfaces 4. Extensions 5. Experiments

Plan 1. Motivation 2. Characterizing Safe, Permissive Interfaces 3. Computing Safe, Permissive Interfaces 4. Extensions 5. Experiments

Typestate Interpretations n0n0 n1n1 acq rel n2n2 acq read rel Interface is a Typestate System - Abstraction of library’s internal state Typestate Interpretation - Overapprox possible internal states a=0 a0a0 e0e0 (P2) Every edge: Post(r, f ) µ r’ n n’ f r r’ (P1) Initial states in r 0 n0n0 r0r0

Typestate Interpretations acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} n0n0 n1n1 acq n2n2 a=0 a0a0 e0e0 (P2) Every edge: Post(r, f ) µ r’ n n’ f r r’

Typestate Interpretations n0n0 n1n1 n2n2 a=0 a0a0 e0e0 rel read read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} (P2) Every edge: Post(r, f ) µ r’ n n’ f r r’

Typestate Interpretations n0n0 n1n1 n2n2 a=0 a0a0 e0e0 rel rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} (P2) Every edge: Post(r, f ) µ r’ n n’ f r r’

Typestate Interpretations n0n0 n1n1 acq rel n2n2 acq read rel Interface is a Typestate System - Abstraction of library’s internal state Typestate Interpretation - Overapprox possible internal states a=0 a0a0 e0e0 (P2) Every edge: Post(r, f ) µ r’ n n’ f r r’ (P1) Initial states in r 0 n0n0 r0r0

Safe Interpretations Interface is a Typestate System - Abstraction of library’s internal state Typestate Interpretation - Overapprox possible internal states (P2) Every edge: Post(r, f ) µ r’ n n’ f r r’ (P1) Initial states in r 0 n0n0 r0r0 (P3) Every legal typestate: r µ : Err n r n0n0 n1n1 acq rel n2n2 acq read rel a=0 a0a0 e0e0

Safe Interpretations Theorem: Safe Interpretation implies Safe Interface (P2) Every edge: Post(r, f ) µ r’ n n’ f r r’ (P1) Initial states in r 0 n0n0 r0r0 (P3) Every legal typestate: r µ : Err n r n0n0 n1n1 acq rel n2n2 acq read rel a=0 a0a0 e0e0

Permissive Interpretations Interface is a Typestate System - Abstraction of library’s internal state Typestate Interpretation - Overapprox possible internal states (P2) Every edge: Post(r, f ) µ r’ n n’ f r r’ (P1) Initial states in r 0 n0n0 r0r0 (P4) Every illegal typestate: r µ Err n r n0n0 n1n1 acq rel n2n2 acq read rel a=0 a0a0 e0e0

Permissive Interpretations (P2) Every edge: Post(r, f ) µ r’ n n’ f r r’ (P1) Initial states in r 0 n0n0 r0r0 (P4) Every illegal typestate: r µ Err n r Theorem: Permissive Interpretation implies Permissive Interface n0n0 n1n1 acq rel n2n2 acq read rel a=0 a0a0 e0e0

Sanity Check API n0n0 n1n1 acq /x rel /x n2n2 acq/x write read write read rel/x Q: Why not a permissive interface ? Static e=0, a=NULL, x=0; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;} acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;} write(){ if(x!=0){ m_wr(a); } else e:=1; return;} write(){ if(x!=0){ m_wr(a); } else e:=1; return;} relx(){ a:=NULL; x:=0;} relx(){ a:=NULL; x:=0;} a=0 a0a0 e0e0

Sanity Check n1n1 n2n2 write write(){ if(x!=0){ m_wr(a); } else e:=1; return;} write(){ if(x!=0){ m_wr(a); } else e:=1; return;} a0a0 e0e0 A: (P2) fails! Not an Interpretation (P2) Every edge: Post(r, f ) µ r’ n n’ f r r’ Q: Why not a permissive interface ? e  0 Ç e=0

Sanity Check n1n1 n2n2 write write(){ if(x!=0){ m_wr(a); } else e:=1; return;} write(){ if(x!=0){ m_wr(a); } else e:=1; return;} a0a0 e  0 Ç e=0 (P4) Every illegal typestate: r µ Err n r A: (P4) fails! Not Permissive Interpretation Q: Why not a permissive interface ?

Plan 1. Motivation 2. Characterizing Safe, Permissive Interfaces 3. Computing Safe, Permissive Interfaces 4. Extensions 5. Experiments

Computing Interfaces Problem A: Interface Checking Given Library, candidate interface I, abstraction  Check if I is safe, permissive. Problem B: Interface Reconstruction Given Library, abstraction , Reconstruct a safe, permissive interface I. Problem C: Interface Inference Given Library, Infer a safe, permissive interface I.

A. Interface Checking Check Safe, Permissive independently Problem A: Interface Checking Given Library, candidate interface I, abstraction  Check if I is safe, permissive.

A. Interface Checking [Safe] Interface n0n0 acq rel n2n2 acq read rel Static e=0; Static a=NULL; Static e=0; Static a=NULL; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} Problem A: Interface Checking Given Library, candidate interface I, abstraction  Check if I is safe, permissive. Library n1n1

A. Interface Checking [Safe] Interface Client Static e=0; Static a=NULL; Static e=0; Static a=NULL; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} Idea: Analyze Interface Client + Library Verify assertion: Client in legal location ) Library in legal state Library n0n0 acq rel n2n2 acq read rel n1n1 Legal e=0 Error e!=0 Library States n

B. Interface Checking [Permissive] Interface n0n0 acq rel n2n2 acq read rel Static e=0; Static a=NULL; Static e=0; Static a=NULL; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} Problem B: Interface Checking Given Library, candidate interface I, abstraction  Check if I is safe, permissive. Library n1n1

B. Interface Checking [Permissive] Interface Client Static e=0; Static a=NULL; Static e=0; Static a=NULL; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} Idea: Analyze Interface Client + Library Verify assertion: Client in illegal location ) Library in illegal state Library n0n0 acq rel n2n2 acq read rel n1n1 Legal e=0 Error e!=0 Library States n

A. Interface Checking Safe, Permissive checkable by Assertion Verification! Problem A: Interface Checking Given Library, candidate interface I, abstraction  Check if I is safe, permissive.

Abstract Reachability Graphs Safe, Permissive checkable by Assertion Verification! Problem A: Interface Checking Given Library, candidate interface I, abstraction  Check if I is safe, permissive.

Abstract Reachability Graphs Static e=0; Static a=NULL; Static e=0; Static a=NULL; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} n0n0 acq rel n2n2 acq read rel n1n1  ={ a=0,e=0 } a=0,e=0 0

Abstract Reachability Graphs Static e=0; Static a=NULL; Static e=0; Static a=NULL; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} n0n0 acq rel n2n2 acq read rel n1n1  ={ a=0,e=0 } a=0,e=0 0 1 acq() : a=0, e=0

Abstract Reachability Graphs Static e=0; Static a=NULL; Static e=0; Static a=NULL; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} n0n0 acq rel n2n2 acq read rel n1n1  ={ a=0,e=0 } a=0,e=0 0 1 acq() : a=0, e=0 rel() a=0,e=0 0

Abstract Reachability Graphs Static e=0; Static a=NULL; Static e=0; Static a=NULL; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} n0n0 acq rel n2n2 acq read rel n1n1  ={ a=0,e=0 } a=0,e=0 0 1 acq() : a=0, e=0 rel() a=0,e=0 0

Abstract Reachability Graphs Static e=0; Static a=NULL; Static e=0; Static a=NULL; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} n0n0 acq rel n2n2 acq read rel n1n1  ={ a=0,e=0 } a=0,e=0 0 1 acq() : a=0, e=0 rel() a=0,e=0 0 rel()

Abstract Reachability Graphs Static e=0; Static a=NULL; Static e=0; Static a=NULL; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} n0n0 acq rel n2n2 acq read rel n1n1  ={ a=0,e=0 } a=0,e=0 0 1 acq() : a=0, e=0 rel() a=0, : e=0 2 : e=0 read()

Abstract Reachability Graphs Static e=0; Static a=NULL; Static e=0; Static a=NULL; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} n0n0 acq rel n2n2 acq read rel n1n1  ={ a=0,e=0 } a=0,e=0 0 1 acq() : a=0, e=0 rel() 2 acq() 2 : e=0 read()

Abstract Reachability Graphs Static e=0; Static a=NULL; Static e=0; Static a=NULL; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} n0n0 acq rel n2n2 acq read rel n1n1  ={ a=0,e=0 } a=0,e=0 0 1 acq() : a=0, e=0 rel() 2 : e=0 read() acq()

Abstract Reachability Graphs Static e=0; Static a=NULL; Static e=0; Static a=NULL; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} n0n0 acq rel n2n2 acq read rel n1n1  ={ a=0,e=0 } a=0,e=0 0 1 acq() : a=0, e=0 rel() 2 : e=0 1 read() acq() read() : a=0, e=0

Abstract Reachability Graphs Static e=0; Static a=NULL; Static e=0; Static a=NULL; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} n0n0 acq rel n2n2 acq read rel n1n1  ={ a=0,e=0 } a=0,e=0 0 1 acq() : a=0, e=0 rel() 2 : e=0 read() acq() read()

Abstract Reachability Graphs Static e=0; Static a=NULL; Static e=0; Static a=NULL; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} n0n0 acq rel n2n2 acq read rel n1n1  ={ a=0,e=0 } a=0,e=0 0 1 acq() : a=0, e=0 rel() 2 : e=0 read() acq() read() rel() a=0,e=0 0

Abstract Reachability Graphs Static e=0; Static a=NULL; Static e=0; Static a=NULL; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} n0n0 acq rel n2n2 acq read rel n1n1  ={ a=0,e=0 } a=0,e=0 0 1 acq() : a=0, e=0 rel() 2 : e=0 read() acq() read() rel()

Abstract Reachability Graphs Static e=0; Static a=NULL; Static e=0; Static a=NULL; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} n0n0 acq rel n2n2 acq read rel n1n1 a=0,e=0 0 1 acq() : a=0, e=0 rel() 2 : e=0 read() acq() read() rel() Verify assertion: [Safe] Client in legal location ) Library in legal state n Legal e=0 Error e!=0 Library States

Abstract Reachability Graphs Static e=0; Static a=NULL; Static e=0; Static a=NULL; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} n0n0 acq rel n2n2 acq read rel n1n1 a=0,e=0 0 1 acq() : a=0, e=0 rel() 2 : e=0 read() acq() read() rel() Verify assertion: [Safe] Client in legal location ) Library in legal state n Legal e=0 Error e!=0 Library States

Abstract Reachability Graphs Static e=0; Static a=NULL; Static e=0; Static a=NULL; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} n0n0 acq rel n2n2 acq read rel n1n1 a=0,e=0 0 1 acq() : a=0, e=0 rel() 2 : e=0 read() acq() read() rel() Legal e=0 Error e!=0 Library States Verify assertion: [Permissive] Client in illegal location ) Library in illegal state n

Abstract Reachability Graphs Static e=0; Static a=NULL; Static e=0; Static a=NULL; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} n0n0 acq rel n2n2 acq read rel n1n1 a=0,e=0 0 1 acq() : a=0, e=0 rel() 2 : e=0 read() acq() read() rel() Legal e=0 Error e!=0 Library States Verify assertion: [Permissive] Client in illegal location ) Library in illegal state n

A. Interface Checking n0n0 acq rel n2n2 acq read rel n1n1 a=0,e=0 0 1 acq() : a=0, e=0 rel() 2 : e=0 read() acq() read() rel() Safe, Permissive Permissive assertion: Client in illegal location ) Library in illegal state Safe assertion: Client in legal location ) Library in legal state

A. Interface Checking n0n0 acq rel n2n2 acq read rel n1n1 a=0,e=0 0 1 acq() : a=0, e=0 rel() 2 : e=0 read() acq() read() rel() Safe, Permissive Abstract Reach. Graph, Typestate Interpretation Safe Assertion, Safe Interpretation Permissive Assertion, Permissive Interpretation

Computing Interfaces Problem A: Interface Checking Given Library, candidate interface I, abstraction  Check if I is safe, permissive. Problem B: Interface Reconstruction Given Library, abstraction , Reconstruct a safe, permissive interface I. Problem C: Interface Inference Given Library, Infer a safe, permissive interface I. Solution: Assertion verification, Abstract Reach. Graph

B. Interface Reconstruction Static e=0; Static a=NULL; Static e=0; Static a=NULL; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} Problem B: Interface Reconstruction Given Library, abstraction , Reconstruct a safe, permissive interface I. Library  ={ a=0,e=0 } Abstraction

B. Interface Reconstruction Maximal Client Static e=0; Static a=NULL; Static e=0; Static a=NULL; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} Idea: I = Abs Reach Graph of Max Client + Library (using  ) ARG Vertices w/ legal library state ) legal typestates ARG Vertices w/ illegal library state ) illegal typestates Library acqread rel  ={ a=0,e=0 } Abstraction

ARG of Max+Library Maximal Client Static e=0; Static a=NULL; Static e=0; Static a=NULL; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} Library acqread rel  ={ a=0,e=0 } Abstract Reach Graph a=0,e=0 acq() : a=0, e=0 rel() : e=0 read() acq() read() rel()

ARG of Max+Library Maximal Client Static e=0; Static a=NULL; Static e=0; Static a=NULL; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} Library acqread rel Abstract Reach Graph a=0,e=0 acq() : a=0, e=0 rel() : e=0 read() acq() read() rel() ARG Vertices w/ legal library state ) legal typestates ARG Vertices w/ illegal library state ) illegal typestates

ARG of Max+Library Maximal Client Static e=0; Static a=NULL; Static e=0; Static a=NULL; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} Library acqread rel Abstract Reach Graph a=0,e=0 acq() : a=0, e=0 rel() : e=0 read() acq() read() rel() ARG Vertices w/ legal library state ) legal typestates ARG Vertices w/ illegal library state ) illegal typestates n0n0 n1n1

ARG of Max+Library Maximal Client Static e=0; Static a=NULL; Static e=0; Static a=NULL; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} Library acqread rel Abstract Reach Graph a=0,e=0 acq() : a=0, e=0 rel() : e=0 read() acq() read() rel() ARG Vertices w/ legal library state ) legal typestates ARG Vertices w/ illegal library state ) illegal typestates n0n0 n1n1 n2n2

ARG of Max+Library Maximal Client Static e=0; Static a=NULL; Static e=0; Static a=NULL; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} Library acqread rel Interface ! a=0,e=0 : a=0, e=0 : e=0 n0n0 n1n1 n2n2 acq rel read rel acq read

ARG of Max+Library Interface a=0,e=0 : a=0, e=0 : e=0 Predicate Labels = Typestate Interpretation n0n0 n1n1 n2n2 acq rel read rel acq read Safe, Permissive by construction

Computing Interfaces Problem A: Interface Checking Given Library, candidate interface I, abstraction  Check if I is safe, permissive. Problem B: Interface Reconstruction Given Library, abstraction , Reconstruct a safe, permissive interface I. Problem C: Interface Inference Given Library, Infer a safe, permissive interface I. Solution: Assertion verification, Abstract Reach. Graph Solution: Interface = ARG ( w.r.t.  ) of Max Client + Library

Computing Interfaces Problem A: Interface Checking Given Library, candidate interface I, abstraction  Check if I is safe, permissive. Problem B: Interface Reconstruction Given Library, abstraction , Reconstruct a safe, permissive interface I. Problem C: Interface Inference Given Library, Infer a safe, permissive interface I. Solution: Assertion verification, Abstract Reach. Graph Solution: Interface = ARG ( w.r.t.  ) of Max Client + Library

C. Interface Inference Require sufficiently precise abstraction  - Then B (reconstruction) suffices Imprecise abstraction ) imprecise Abstract Reach Graph - Vertex w/ label containing both legal and illegal lib states Q: How to deal w/ imprecise vertices ? Idea: Any call sequence into vertex is either legal or illegal Legal sequence ) Infeasible path to Err Illegal sequence ) Infeasible path to : Err Refine abstraction using call sequence into imprecise vertex Repeat until ARG precise, i.e. Interface found

Example Static e=0, a=NULL, x=0; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;} acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;} write(){ if(x!=0){ m_wr(a); } else e:=1; return;} write(){ if(x!=0){ m_wr(a); } else e:=1; return;} relx(){ a:=NULL; x:=0;} relx(){ a:=NULL; x:=0;}  ={ e=0 } acq/x write rel/x read Abstract Reach Graph e=0 acq/x() e=0 Ç : e=0 rel/x() * read() write()

Example Static e=0, a=NULL, x=0; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;} acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;} write(){ if(x!=0){ m_wr(a); } else e:=1; return;} write(){ if(x!=0){ m_wr(a); } else e:=1; return;} relx(){ a:=NULL; x:=0;} relx(){ a:=NULL; x:=0;} acq/x write rel/x read Imprecise ! read() e=0 Ç : e=0 Call read() is illegal ) Paths to e=0 infeasible New predicate a=0 New ARG prohibits immediate call to read

Example Static e=0, a=NULL, x=0; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;} acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;} write(){ if(x!=0){ m_wr(a); } else e:=1; return;} write(){ if(x!=0){ m_wr(a); } else e:=1; return;} relx(){ a:=NULL; x:=0;} relx(){ a:=NULL; x:=0;}  ={ e=0,a=0 } acq/x write rel/x read Abstract Reach Graph rel/x() a=0,e=0 acq /x : a=0, e=0 : e=0 read() rel /x acq /x write() : e=0 Ç e=0

Example Static e=0, a=NULL, x=0; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;} acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;} write(){ if(x!=0){ m_wr(a); } else e:=1; return;} write(){ if(x!=0){ m_wr(a); } else e:=1; return;} relx(){ a:=NULL; x:=0;} relx(){ a:=NULL; x:=0;} acq/x write rel/x read acqx() write() : e=0 Ç e=0 Sequence acqx();write() is legal ) Paths to e!=0 infeasible New predicate x=0 New ARG allows sequence acqx ;write

Example Static e=0, a=NULL, x=0; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;} acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;} write(){ if(x!=0){ m_wr(a); } else e:=1; return;} write(){ if(x!=0){ m_wr(a); } else e:=1; return;} relx(){ a:=NULL; x:=0;} relx(){ a:=NULL; x:=0;} acq/x write rel/x read Safe, Permissive Interface rel/x() a=0, e=0, x=0 acq : e=0 read() rel /x acqx write() rel /x read() : a=0, e=0 x=0 : a=0, e=0, x=0

Example Static e=0, a=NULL, x=0; acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;} acqx(){ if(a==NULL){ a:=m_new(); x:=1; } else e:=1;} write(){ if(x!=0){ m_wr(a); } else e:=1; return;} write(){ if(x!=0){ m_wr(a); } else e:=1; return;} relx(){ a:=NULL; x:=0;} relx(){ a:=NULL; x:=0;} Safe, Permissive Interface n0n0 n1n1 acq n3n3 read rel/x n2n2 acqx relx write read : a=0, e=0 x=0 rel/x() a=0, e=0, x=0 acq : a=0, e=0, x=0 : e=0 read() rel /x acqx write() rel /x read()

Computing Interfaces Problem A: Interface Checking Given Library, candidate interface I, abstraction  Check if I is safe, permissive. Problem B: Interface Reconstruction Given Library, abstraction , Reconstruct a safe, permissive interface I. Problem C: Interface Inference Given Library, Infer a safe, permissive interface I. Solution: Assertion verification, Abstract Reach. Graph Solution: Interface = ARG ( w.r.t.  ) of Max Client + Library Solution: Refine abstraction using imprecise ARG vertices

Two Requirements, Two Abstractions Safe, Permissive: Orthogonal –Different abstractions suffice to prove each  =  safe [  permissive –  safe : calls allowed µ legal calls –  permissive : calls disallowed µ illegal calls 1.Build largest safe Interface I,using  safe Build ARG, imprecise vertices illegal 2.Check I is permissive, using  permissive Fails: possibly legal, prohibited sequence to imprecise 3.If sequence illegal then Refine  permissive legal then Refine  safe

Safety Verification vs Interface Construction 1. Error not reachable 2. Show always legal Find one illegal sequence 3. Refine: Infeasible path to Error 5. Refine: Fewer behaviors 1. Error reachable 2. Find all legal sequences Find all illegal sequences 3. Refine: Infeasible path to Error (Safe) OR Infeasible path to Legal (Perm) 5. Refine: More behaviors

Plan 1. Motivation 2. Characterizing Safe, Permissive Interfaces 3. Computing Safe, Permissive Interfaces 4. Extensions 5. Experiments

Extensions: Outputs Outputs allow non-determinism in library n0n0 n1n1 acq,1 rel n2n2 acq,* read rel acq,0 Static e=0; Static a=NULL; Static e=0; Static a=NULL; acq(){ if (...) return 0; else { if(a==NULL){ a:=m_new(); } else e:=1; return 1; } acq(){ if (...) return 0; else { if(a==NULL){ a:=m_new(); } else e:=1; return 1; } read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} read(){ if(a!=NULL){ a:=m_rd(a); } else e:=1; return;} rel(){ a:=NULL; return;} rel(){ a:=NULL; return;} Library Safe, Permissive Interface

Extensions Heirarchy: Library built using of sub-libraries Construct interface using sub-interfaces Decomposition: Complex illegal States give large Interface Partition: small interface per partition Multiple Correlated Libraries: Interface = Typestate Hypergraph

Plan 1. Motivation 2. Characterizing Safe, Permissive Interfaces 3. Computing Safe, Permissive Interfaces 4. Extensions 5. Experiments

Experiments Implemented inside BLAST Find interfaces for Java classes (JDK 1.4) –Input: Class, Error states (Exception raised) –Tool Automatically finds predicates, interfaces Classes - Signature, ServerTableEntry, ListItr, Socket –Private state variables determine interface –Partition methods by which variables they affect Socket: 6 Predicates, <30s connect ! getInputStream ! shutDownInput ! Close

To sum up… Modular PA requires Safe,Permissive Interfaces –Safe : I µ legal sequences –Perm: legal sequences µ I Interface = Typestate Graph –Safe, Permissive via Typestate Interpretation Compute Interface via Abs. Reach. Graph –Issue: Permissive “lower bound” requirement –Solution: : I µ illegal sequences Implementation: –Safe, Permissive Interfaces for Java classes –Automatic synthesis of Typestate Systems

Related Work Whaley-Lam [ISSTA 02] Use data-flow analysis, Error condition via exceptions Bar call to b if a modifies a variable guarding exn branch Not permissive Alur et. al. [POPL 05] Use machine learning to find set of legal sequences after Manually supplied finite abstraction Not permissive Fahndrich-Deline [ECOOP 04] Typestate interpretation Counterexample-Guided Refinement …

Thank you