Lazy Abstraction
-
Upload
hayes-bauer -
Category
Documents
-
view
56 -
download
1
description
Transcript of Lazy Abstraction
Lazy Abstraction
Lecture 3 : Partial Analysis
Ranjit JhalaUC San Diego
With: Tom Henzinger, Rupak Majumdar, Ken McMillan, Gregoire Sutre
A Problem with Program Analysis
Whole Program Analysis not always possible • Availability: Client code missing • Scalability: Whole system too large
Client Client LibraryLibrary
Partial Program Analysis
Partial Program Analysis • Find interface for Library• Use interface to verify client
Client Client LibraryLibrary
Partial Program Analysis
Availability: Interface independent of ClientScalability: Interface small, abstraction of Library
LibraryLibrary
Interface
What is an Interface ?
Interface : Constraints on legal uses of API
• API Calls after which library is in a legal state
LibraryLibraryLegal Error
Interface Library StatesAPI
LibraryLibrary
Legal Error
Example
Legal e=0
Errore!=0
Library StatesInterface API
n0
n1
acq rel n2acq
read
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;}
n0
n1
acq/x rel/x n2acq/xwrite
readwrite
read
rel/x
n0
n1
acq rel n2acq
read
read
rel
Safety Not Enough!Interface API
Disallows calls to write • Useless for Partial Program Analysis
Static e=0, a=NULL, x=0;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 InterfacesInterface API
n0
n1
acq
n3read
rel/x
Permissive: Legal Call Sequences µ InterfacePartial Analysis: Safe + Permissive Interfaces
Static e=0, a=NULL, x=0;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;}
n2
acqx
relx
writeread
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
n0
n1
acq rel n2acq
read
read
rel
Interface is a Typestate System
- Abstraction of library’s internal state
Typestate Interpretation
- Overapprox possible internal statesa=0
a0 e0
(P2) Every edge: Post(r,f) µ r’
n n’f
r r’
(P1) Initial states in r0
n0 r0
Typestate Interpretations
acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}
acq(){ if(a==NULL){ a:=m_new(); } else e:=1; return;}n0
n1
acq n2acq
a=0
a0 e0
(P2) Every edge: Post(r,f) µ r’
n n’f
r r’
Typestate Interpretations
n0
n1
n2
a=0
a0 e0
rel
read
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
n0
n1
n2
a=0
a0 e0
rel
relrel(){ a:=NULL; return;}
rel(){ a:=NULL; return;}
(P2) Every edge: Post(r,f) µ r’
n n’f
r r’
Typestate Interpretations
n0
n1
acq rel n2acq
read
read
rel
Interface is a Typestate System
- Abstraction of library’s internal state
Typestate Interpretation
- Overapprox possible internal statesa=0
a0 e0
(P2) Every edge: Post(r,f) µ r’
n n’f
r r’
(P1) Initial states in r0
n0 r0
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 r0
n0 r0
(P3) Every legal typestate: r µ : Err
n r
n0
n1
acq rel n2acq
read
read
rel
a=0
a0 e0
Safe Interpretations
Theorem: Safe Interpretation implies Safe Interface
(P2) Every edge: Post(r,f) µ r’
n n’f
r r’
(P1) Initial states in r0
n0 r0
(P3) Every legal typestate: r µ : Err
n r
n0
n1
acq rel n2acq
read
read
rel
a=0
a0 e0
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 r0
n0 r0
(P4) Every illegal typestate: r µ Err
n r
n0
n1
acq rel n2acq
read
read
rel
a=0
a0 e0
Permissive Interpretations
(P2) Every edge: Post(r,f) µ r’
n n’f
r r’
(P1) Initial states in r0
n0 r0
(P4) Every illegal typestate: r µ Err
n r
Theorem: Permissive Interpretation implies Permissive Interface
n0
n1
acq rel n2acq
read
read
rel
a=0
a0 e0
Sanity CheckAPI
n0
n1
acq/x
rel/x n2
acq/xwrite
readwrite
read
rel/x
Q: Why not a permissive interface ?
Static e=0, a=NULL, x=0;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
a0 e0
Sanity Check
n1
n2
write
write(){ if(x!=0){ m_wr(a); } else e:=1; return;}
write(){ if(x!=0){ m_wr(a); } else e:=1; return;}a0
e0
A: (P2) fails! Not an Interpretation
(P2) Every edge: Post(r,f) µ r’
n n’f
r r’
Q: Why not a permissive interface ?
e0 Ç e=0
Sanity Check
n1
n2
write
write(){ if(x!=0){ m_wr(a); } else e:=1; return;}
write(){ if(x!=0){ m_wr(a); } else e:=1; return;}a0
e0 Ç 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
n0
acq rel n2
acq
read
read
relStatic 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
n1
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
n0
acq rel n2
acq
read
read
rel
n1
Legal e=0
Errore!=0
Library States
n
B. Interface Checking [Permissive]
Interface
n0
acq rel n2
acq
read
read
relStatic 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
n1
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
n0
acq rel n2
acq
read
read
rel
n1
Legal e=0
Errore!=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;}
n0
acq rel n2
acq
read
read
rel
n1
={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;}
n0
acq rel n2
acq
read
read
rel
n1
={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;}
n0
acq rel n2
acq
read
read
rel
n1
={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;}
n0
acq rel n2
acq
read
read
rel
n1
={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;}
n0
acq rel n2
acq
read
read
rel
n1
={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;}
n0
acq rel n2
acq
read
read
rel
n1
={a=0,e=0}
a=0,e=0
0
1
acq()
: a=0, e=0
rel()
a=0,: e=02 : 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;}
n0
acq rel n2
acq
read
read
rel
n1
={a=0,e=0}
a=0,e=0
0
1
acq()
: a=0, e=0
rel()
2
acq()
2
: e=0
: 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;}
n0
acq rel n2
acq
read
read
rel
n1
={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;}
n0
acq rel n2
acq
read
read
rel
n1
={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;}
n0
acq rel n2
acq
read
read
rel
n1
={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;}
n0
acq rel n2
acq
read
read
rel
n1
={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;}
n0
acq rel n2
acq
read
read
rel
n1
={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;}
n0
acq rel n2
acq
read
read
rel
n1
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 staten
Legal e=0
Errore!=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;}
n0
acq rel n2
acq
read
read
rel
n1
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 staten
Legal e=0
Errore!=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;}
n0
acq rel n2
acq
read
read
rel
n1
a=0,e=0
0
1
acq()
: a=0, e=0
rel()
2 : e=0
read()
acq()
read()
rel()
Legal e=0
Errore!=0
Library States
Verify assertion: [Permissive]
Client in illegal location ) Library in illegal staten
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;}
n0
acq rel n2
acq
read
read
rel
n1
a=0,e=0
0
1
acq()
: a=0, e=0
rel()
2 : e=0
read()
acq()
read()
rel()
Legal e=0
Errore!=0
Library States
Verify assertion: [Permissive]
Client in illegal location ) Library in illegal staten
A. Interface Checking
n0
acq rel n2
acq
read
read
rel
n1
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
n0
acq rel n2
acq
read
read
rel
n1
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 ReconstructionStatic 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 typestatesARG Vertices w/ illegal library state ) illegal typestates
Library
acq read
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
acq read
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
acq read
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 typestatesARG 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
acq read
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 typestatesARG Vertices w/ illegal library state ) illegal typestates
n0
n1
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
acq read
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 typestatesARG Vertices w/ illegal library state ) illegal typestates
n0
n1
n2
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
acq read
rel
Interface !
a=0,e=0
: a=0, e=0
: e=0
n0
n1
n2acq rel
read
rel
acq
read
ARG of Max+Library
Interface
a=0,e=0
: a=0, e=0
: e=0Predicate Labels=
Typestate Interpretation
n0
n1
n2acq 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 InferenceRequire 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 :ErrRefine abstraction using call sequence into imprecise vertex Repeat until ARG precise, i.e. Interface found
ExampleStatic e=0, a=NULL, x=0;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=0acq/x()
e=0 Ç : e=0
rel/x()
*
read()write()
ExampleStatic e=0, a=NULL, x=0;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
ExampleStatic e=0, a=NULL, x=0;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
ExampleStatic e=0, a=NULL, x=0;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
ExampleStatic e=0, a=NULL, x=0;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=0acq
: e=0read()
rel/x
acqx
write()
rel/x
read()
: a=0 , e=0
x=0
: a=0, e=0, x=0
ExampleStatic e=0, a=NULL, x=0;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
n0
n1
acq
n3read
rel/x
n2
acqx
relx
writeread
: a=0 , e=0
x=0
rel/x()
a=0,e=0,x=0acq
: a=0, e=0, x=0
: e=0read()
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
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: OutputsOutputs allow non-determinism in library
n0
n1
acq,1 rel n2acq,*
read
read
relacq,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;}
LibrarySafe, Permissive Interface
ExtensionsHeirarchy: 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• 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…• Partial 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
So … what is Lazy Abstraction ?–Theorem Proving ?–Dataflow Analysis ?–Model Checking ?
Verification by Theorem Proving
1. Loop Invariants2. Logical formula3. Check Validity
Invariant: lock Æ new = old
Ç : lock Æ new old
Example ( ) {1: do{ lock(); old = new;
q = q->next;2: if (q != NULL){3: q->data = new;
unlock(); new ++; }4: } while(new != old);5: unlock (); return;}
Example ( ) {1: do{ lock(); old = new;
q = q->next;2: if (q != NULL){3: q->data = new;
unlock(); new ++; }4: } while(new != old);5: unlock (); return;}
Verification by Theorem Proving
1. Loop Invariants2. Logical formula3. Check Validity
- Loop Invariants- Multithreaded Programs + Behaviors encoded in logic+ Decision Procedures-
Example ( ) {1: do{ lock(); old = new;
q = q->next;2: if (q != NULL){3: q->data = new;
unlock(); new ++; }4: } while(new != old);5: unlock (); return;}
Example ( ) {1: do{ lock(); old = new;
q = q->next;2: if (q != NULL){3: q->data = new;
unlock(); new ++; }4: } while(new != old);5: unlock (); return;} Precis
e[ESC]
Verification by Program Analysis
1. Dataflow Facts2. Constraint
System3. Solve constraints
Example ( ) {1: do{ lock(); old = new;
q = q->next;2: if (q != NULL){3: q->data = new;
unlock(); new ++; }4: } while(new != old);5: unlock (); return;}
Example ( ) {1: do{ lock(); old = new;
q = q->next;2: if (q != NULL){3: q->data = new;
unlock(); new ++; }4: } while(new != old);5: unlock (); return;}
- Imprecision due to fixed facts
+ Abstraction
+ Type/Flow AnalysesScalable[CQUAL, ESP, MC]
Verification by Model Checking
1. (Finite State) Program
2. State Transition Graph
3. Reachability
Example ( ) {1: do{ lock(); old = new;
q = q->next;2: if (q != NULL){3: q->data = new;
unlock(); new ++; }4: } while(new != old);5: unlock (); return;}
Example ( ) {1: do{ lock(); old = new;
q = q->next;2: if (q != NULL){3: q->data = new;
unlock(); new ++; }4: } while(new != old);5: unlock (); return;}
- Pgm ! Finite state model
- State explosion + State Exploration+ CounterexamplesPrecise[SPIN, SMV, Bandera,JPF ]
Combining StrengthsTheorem Proving
- loop invariants
+ Behaviors encoded in logicRefine+ Theorem proversComputing Successors,Refine
Program Analysis
- Imprecise+ AbstractionShrink state space
Model Checking- Finite-state model, state explosion+ State Space ExplorationPath Sensitive Analysis+ CounterexamplesFinding Relevant Facts
Lazy Abstraction
www.cs.uc{sd,la}.edu/~blast/www.cs.uc{sd,la}.edu/~blast/
Thank youThank you