Lazy Abstraction Lecture 3 Partial Analysis Ranjit Jhala
Lazy Abstraction Lecture 3 : Partial Analysis Ranjit Jhala UC San Diego With: Tom Henzinger, Rupak Majumdar, Ken Mc. Millan, Gregoire Sutre
A Problem with Program Analysis Client Library Whole Program Analysis not always possible • • Availability: Client code missing Scalability: Whole system too large
Partial Program Analysis Client Library Partial Program Analysis • • Find interface for Library Use interface to verify client
Partial Program Analysis Interface Library Availability: Interface independent of Client Scalability: Interface small, abstraction of Library
What is an Interface ? Interface API Library States Library Legal Error Interface : Constraints on legal uses of API • API Calls after which library is in a legal state
Example Interface rel n 0 acq read rel n 1 read n 2 acq API Static e=0; Static a=NULL; acq(){ if(a==NULL){ a: = m_new(); } else e: =1; return; } read(){ if(a!=NULL){ a: = m_rd(a); } else e: =1; return; } rel(){ a: =NULL; return; } Library States Legal e=0 Safe: Interface µ Legal Call Sequences Error e!=0
Safety Not Enough! Interface API rel /x read write n 0 acq /x rel n 1 n 2 acq/x write read Static e=0, a=NULL, x=0; acq(){ acqx(){ if(a==NULL){ a: =m_new(); } else e: =1; x: =1; return; } } else e: =1; } read(){ write(){ if(a!=NULL){ if(x!=0){ a: =m_rd(a); m_wr(a); } else e: =1; return; } rel(){ relx(){ a: =NULL; return; } x: =0; } Disallows calls to write • Useless for Partial Program Analysis
Permissive Interfaces Interface API rel/x acq n 1 read n 0 relx n 3 acqx n 2 write read Static e=0, a=NULL, x=0; acq(){ acqx(){ if(a==NULL){ a: =m_new(); } else e: =1; x: =1; return; } } else e: =1; } read(){ write(){ if(a!=NULL){ if(x!=0){ a: =m_rd(a); m_wr(a); } else e: =1; return; } rel(){ relx(){ a: =NULL; return; } x: =0; } Permissive: Legal Call Sequences µ Interface Partial Analysis: Safe + Permissive Interfaces
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 rel n 0 a=0 acq a 0 read rel n 1 read n 2 acq e 0 Interface is a Typestate System - Abstraction of library’s internal state Typestate Interpretation - Overapprox possible internal states (P 1) Initial states in r 0 (P 2) Every edge: Post(r, f) µ r’ n 0 n r 0 f r n’ r’
Typestate Interpretations a=0 n 0 acq a 0 acq(){ if(a==NULL){ a: =m_new(); } else e: =1; return; } n 2 n 1 acq e 0 (P 2) Every edge: Post(r, f) µ r’ n f r n’ r’
Typestate Interpretations read(){ if(a!=NULL){ a: =m_rd(a); } else e: =1; return; } rel a=0 n 0 read n 2 a 0 n 1 read e 0 (P 2) Every edge: Post(r, f) µ r’ n f r n’ r’
Typestate Interpretations rel(){ a: =NULL; return; } rel a=0 n 0 rel a 0 n 1 n 2 e 0 (P 2) Every edge: Post(r, f) µ r’ n f r n’ r’
Typestate Interpretations rel n 0 a=0 acq a 0 read rel n 1 read n 2 acq e 0 Interface is a Typestate System - Abstraction of library’s internal state Typestate Interpretation - Overapprox possible internal states (P 1) Initial states in r 0 (P 2) Every edge: Post(r, f) µ r’ n 0 n r 0 f r n’ r’
Safe Interpretations rel n 0 a=0 acq a 0 read rel n 1 read n 2 acq e 0 Interface is a Typestate System - Abstraction of library’s internal state Typestate Interpretation - Overapprox possible internal states (P 1) Initial states in r 0 (P 2) Every edge: Post(r, f) µ r’ n 0 n (P 3) Every legal typestate: r µ : Err r 0 f n’ r n r r’
Safe Interpretations Theorem: Safe Interpretation implies Safe Interface rel n 0 a=0 acq a 0 read rel n 1 read n 2 acq e 0 (P 1) Initial states in r 0 (P 2) Every edge: Post(r, f) µ r’ n 0 n (P 3) Every legal typestate: r µ : Err r 0 f n’ r n r r’
Permissive Interpretations rel n 0 a=0 acq a 0 read rel n 1 read n 2 acq e 0 Interface is a Typestate System - Abstraction of library’s internal state Typestate Interpretation - Overapprox possible internal states (P 1) Initial states in r 0 (P 2) Every edge: Post(r, f) µ r’ n 0 n r 0 f r (P 4) Every illegal typestate: n r µ Err n’ r r’
Permissive Interpretations Theorem: Permissive Interpretation implies Permissive Interface rel n 0 a=0 acq a 0 read rel n 1 read n 2 acq e 0 (P 1) Initial states in r 0 (P 2) Every edge: Post(r, f) µ r’ n 0 n r 0 f r (P 4) Every illegal typestate: n r µ Err n’ r r’
Sanity Check API rel/x acq /x a 0 read write n 0 a=0 rel /x n 1 read n 2 acq/x e 0 write Static e=0, a=NULL, x=0; acq(){ acqx(){ if(a==NULL){ a: =m_new(); } else e: =1; x: =1; return; } } else e: =1; } read(){ write(){ if(a!=NULL){ if(x!=0){ a: =m_rd(a); m_wr(a); } else e: =1; return; } rel(){ relx(){ a: =NULL; return; } x: =0; } Q: Why not a permissive interface ?
Sanity Check (P 2) Every edge: Post(r, f) µ r’ n 2 a 0 n 1 write ee 00 Ç e=0 n f r n’ r’ write(){ if(x!=0){ m_wr(a); } else e: =1; return; } Q: Why not a permissive interface ? A: (P 2) fails! Not an Interpretation
Sanity Check (P 4) Every illegal typestate: n r µ Err n 2 a 0 n 1 write e 0 Ç e=0 r write(){ if(x!=0){ m_wr(a); } else e: =1; return; } Q: Why not a permissive interface ? A: (P 4) fails! Not Permissive Interpretation
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] rel n 0 read rel acq n 1 n 2 acq read Interface Static e=0; Static a=NULL; acq(){ if(a==NULL){ a: =m_new(); } else e: =1; return; } read(){ if(a!=NULL){ a: =m_rd(a); } else e: =1; return; } rel(){ a: =NULL; return; } Library Problem A: Interface Checking Given Library, candidate interface I, abstraction , Check if I is safe, permissive.
A. Interface Checking [Safe] Static e=0; Static a=NULL; acq(){ if(a==NULL){ a: =m_new(); } else e: =1; return; } read(){ if(a!=NULL){ a: =m_rd(a); } else e: =1; return; } rel(){ a: =NULL; return; } rel n 0 read rel acq n 1 n 2 acq read Interface Client Library States Legal e=0 Library Idea: Analyze Interface Client + Library Verify assertion: Client in legal location n ) Library in legal state Error e!=0
B. Interface Checking [Permissive] rel n 0 read rel acq n 1 n 2 acq read Interface Static e=0; Static a=NULL; acq(){ if(a==NULL){ a: =m_new(); } else e: =1; return; } read(){ if(a!=NULL){ a: =m_rd(a); } else e: =1; return; } rel(){ a: =NULL; return; } Library Problem B: Interface Checking Given Library, candidate interface I, abstraction , Check if I is safe, permissive.
B. Interface Checking [Permissive] rel n 0 read rel acq n 1 n 2 acq read Static e=0; Static a=NULL; acq(){ if(a==NULL){ a: =m_new(); } else e: =1; return; } read(){ if(a!=NULL){ a: =m_rd(a); } else e: =1; return; } rel(){ a: =NULL; return; } Interface Client Library States Legal e=0 Error e!=0 Library Idea: Analyze Interface Client + Library Verify assertion: Client in illegal location n ) Library in illegal state
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 rel n 0 read rel acq n 1 read n 2 acq Static e=0; Static a=NULL; acq(){ if(a==NULL){ a: =m_new(); } else e: =1; return; } read(){ if(a!=NULL){ a: =m_rd(a); } else e: =1; return; } rel(){ a: =NULL; return; } ={a=0, e=0} a=0, e=0 0
Abstract Reachability Graphs rel n 0 read rel acq n 1 read n 2 acq Static e=0; Static a=NULL; acq(){ if(a==NULL){ a: =m_new(); } else e: =1; return; } read(){ if(a!=NULL){ a: =m_rd(a); } else e: =1; return; } rel(){ a: =NULL; return; } ={a=0, e=0} a=0, e=0 0 acq() : a=0, e=0 1
Abstract Reachability Graphs rel n 0 read rel acq n 1 read n 2 acq Static e=0; Static a=NULL; acq(){ if(a==NULL){ a: =m_new(); } else e: =1; return; } read(){ if(a!=NULL){ a: =m_rd(a); } else e: =1; return; } rel(){ a: =NULL; return; } ={a=0, e=0} a=0, e=0 0 rel() acq() : a=0, e=0 1 0 a=0, e=0
Abstract Reachability Graphs rel n 0 read rel acq n 1 read n 2 acq Static e=0; Static a=NULL; acq(){ if(a==NULL){ a: =m_new(); } else e: =1; return; } read(){ if(a!=NULL){ a: =m_rd(a); } else e: =1; return; } rel(){ a: =NULL; return; } ={a=0, e=0} a=0, e=0 0 rel() acq() : a=0, e=0 1 0 a=0, e=0
Abstract Reachability Graphs rel n 0 read rel acq n 1 read n 2 acq Static e=0; Static a=NULL; acq(){ if(a==NULL){ a: =m_new(); } else e: =1; return; } read(){ if(a!=NULL){ a: =m_rd(a); } else e: =1; return; } rel(){ a: =NULL; return; } ={a=0, e=0} rel() a=0, e=0 0 rel() acq() : a=0, e=0 1 0 a=0, e=0
Abstract Reachability Graphs rel n 0 read rel acq n 1 read n 2 acq Static e=0; Static a=NULL; acq(){ if(a==NULL){ a: =m_new(); } else e: =1; return; } read(){ if(a!=NULL){ a: =m_rd(a); } else e: =1; return; } rel(){ a: =NULL; return; } ={a=0, e=0} rel() a=0, e=0 0 e=0 2 : a=0, : acq() : a=0, e=0 read() 1
Abstract Reachability Graphs rel n 0 read rel acq n 1 read n 2 acq Static e=0; Static a=NULL; acq(){ if(a==NULL){ a: =m_new(); } else e: =1; return; } read(){ if(a!=NULL){ a: =m_rd(a); } else e: =1; return; } rel(){ a: =NULL; return; } rel() a=0, e=0 : a=0, e=0 read() 2 : e=0 acq() 1 acq() : e=0 ={a=0, e=0} 0 2
Abstract Reachability Graphs rel n 0 read rel acq n 1 read n 2 acq Static e=0; Static a=NULL; acq(){ if(a==NULL){ a: =m_new(); } else e: =1; return; } read(){ if(a!=NULL){ a: =m_rd(a); } else e: =1; return; } rel(){ a: =NULL; return; } ={a=0, e=0} rel() a=0, e=0 0 2 : e=0 acq() : a=0, e=0 read() acq() 1
Abstract Reachability Graphs rel n 0 read rel acq n 1 read n 2 acq Static e=0; Static a=NULL; acq(){ if(a==NULL){ a: =m_new(); } else e: =1; return; } read(){ if(a!=NULL){ a: =m_rd(a); } else e: =1; return; } rel(){ a: =NULL; return; } ={a=0, e=0} rel() a=0, e=0 0 2 : e=0 acq() : a=0, e=0 read() acq() 1 read() 1 : a=0, e=0
Abstract Reachability Graphs rel n 0 read rel acq n 1 read n 2 acq Static e=0; Static a=NULL; acq(){ if(a==NULL){ a: =m_new(); } else e: =1; return; } read(){ if(a!=NULL){ a: =m_rd(a); } else e: =1; return; } rel(){ a: =NULL; return; } ={a=0, e=0} rel() a=0, e=0 0 2 : e=0 acq() : a=0, e=0 read() acq() 1 read()
Abstract Reachability Graphs rel n 0 read rel acq n 1 read n 2 acq Static e=0; Static a=NULL; acq(){ if(a==NULL){ a: =m_new(); } else e: =1; return; } read(){ if(a!=NULL){ a: =m_rd(a); } else e: =1; return; } rel(){ a: =NULL; return; } rel() a=0, e=0 0 2 : e=0 acq() : a=0, e=0 read() acq() 1 read() rel() 0 ={a=0, e=0} a=0, e=0
Abstract Reachability Graphs rel n 0 read rel acq n 1 read n 2 acq Static e=0; Static a=NULL; acq(){ if(a==NULL){ a: =m_new(); } else e: =1; return; } read(){ if(a!=NULL){ a: =m_rd(a); } else e: =1; return; } rel(){ a: =NULL; return; } ={a=0, e=0} rel() a=0, e=0 0 rel() 2 : e=0 acq() : a=0, e=0 read() acq() 1 read()
Abstract Reachability Graphs rel n 0 read rel acq n 1 read n 2 acq Static e=0; Static a=NULL; acq(){ if(a==NULL){ a: =m_new(); } else e: =1; return; } read(){ if(a!=NULL){ a: =m_rd(a); } else e: =1; return; } rel(){ a: =NULL; return; } rel() a=0, e=0 0 rel() 2 : e=0 acq() : a=0, e=0 read() acq() 1 read() Library States Legal e=0 Verify assertion: [Safe] Client in legal location n ) Library in legal state Error e!=0
Abstract Reachability Graphs rel n 0 read rel acq n 1 read n 2 acq Static e=0; Static a=NULL; acq(){ if(a==NULL){ a: =m_new(); } else e: =1; return; } read(){ if(a!=NULL){ a: =m_rd(a); } else e: =1; return; } rel(){ a: =NULL; return; } rel() a=0, e=0 0 rel() 2 : e=0 acq() : a=0, e=0 read() acq() 1 read() Library States Legal e=0 Verify assertion: [Safe] Client in legal location n ) Library in legal state Error e!=0
Abstract Reachability Graphs rel n 0 read rel acq n 1 read n 2 acq Static e=0; Static a=NULL; acq(){ if(a==NULL){ a: =m_new(); } else e: =1; return; } read(){ if(a!=NULL){ a: =m_rd(a); } else e: =1; return; } rel(){ a: =NULL; return; } rel() a=0, e=0 0 rel() 2 : e=0 acq() : a=0, e=0 read() acq() 1 read() Library States Legal e=0 Verify assertion: [Permissive] Client in illegal location n ) Library in illegal state Error e!=0
Abstract Reachability Graphs rel n 0 read rel acq n 1 read n 2 acq Static e=0; Static a=NULL; acq(){ if(a==NULL){ a: =m_new(); } else e: =1; return; } read(){ if(a!=NULL){ a: =m_rd(a); } else e: =1; return; } rel(){ a: =NULL; return; } rel() a=0, e=0 0 rel() 2 : e=0 acq() : a=0, e=0 read() acq() 1 read() Library States Legal e=0 Verify assertion: [Permissive] Client in illegal location n ) Library in illegal state Error e!=0
A. Interface Checking rel() rel n 0 rel acq n 1 a=0, e=0 read n 2 Safe, Permissive acq read() rel() 2 : e=0 acq() : a=0, e=0 read 0 acq() 1 read() Safe assertion: Client in legal location ) Library in legal state Permissive assertion: Client in illegal location ) Library in illegal state
A. Interface Checking rel() rel n 0 rel acq n 1 read a=0, e=0 read n 2 acq Safe, Permissive 0 rel() 2 : e=0 acq() : a=0, e=0 read() acq() 1 read() 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 , Solution: Assertion verification, Abstract Reach. Graph 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.
B. Interface Reconstruction ={a=0, e=0} Abstraction Static e=0; Static a=NULL; acq(){ if(a==NULL){ a: =m_new(); } else e: =1; return; } read(){ if(a!=NULL){ a: =m_rd(a); } else e: =1; return; } rel(){ a: =NULL; return; } Library Problem B: Interface Reconstruction Given Library, abstraction , Reconstruct a safe, permissive interface I.
B. Interface Reconstruction rel acq read Maximal Client Static e=0; Static a=NULL; acq(){ if(a==NULL){ a: =m_new(); } else e: =1; return; } read(){ if(a!=NULL){ a: =m_rd(a); } else e: =1; return; } rel(){ a: =NULL; return; } ={a=0, e=0} Abstraction Library 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
ARG of Max+Library rel acq read Maximal Client Static e=0; Static a=NULL; acq(){ if(a==NULL){ a: =m_new(); } else e: =1; return; } read(){ if(a!=NULL){ a: =m_rd(a); } else e: =1; return; } rel(){ a: =NULL; return; } Library rel() a=0, e=0 acq() read() rel() : a=0, e=0 : e=0 acq() read() Abstract Reach Graph ={a=0, e=0}
ARG of Max+Library rel acq read Maximal Client Static e=0; Static a=NULL; acq(){ if(a==NULL){ a: =m_new(); } else e: =1; return; } read(){ if(a!=NULL){ a: =m_rd(a); } else e: =1; return; } rel(){ a: =NULL; return; } Library rel() a=0, e=0 acq() read() rel() : a=0, e=0 : e=0 acq() read() Abstract Reach Graph ARG Vertices w/ legal library state ) legal typestates ARG Vertices w/ illegal library state ) illegal typestates
ARG of Max+Library rel acq read Maximal Client Static e=0; Static a=NULL; acq(){ if(a==NULL){ a: =m_new(); } else e: =1; return; } read(){ if(a!=NULL){ a: =m_rd(a); } else e: =1; return; } rel(){ a: =NULL; return; } Library rel() a=0, e=0 acq() : a=0, e=0 n 0 read() rel() n 1 : e=0 acq() read() Abstract Reach Graph ARG Vertices w/ legal library state ) legal typestates ARG Vertices w/ illegal library state ) illegal typestates
ARG of Max+Library rel acq read Maximal Client Static e=0; Static a=NULL; acq(){ if(a==NULL){ a: =m_new(); } else e: =1; return; } read(){ if(a!=NULL){ a: =m_rd(a); } else e: =1; return; } rel(){ a: =NULL; return; } Library rel() a=0, e=0 acq() : a=0, e=0 n 0 read() rel() n 2 : e=0 n 1 acq() read() Abstract Reach Graph ARG Vertices w/ legal library state ) legal typestates ARG Vertices w/ illegal library state ) illegal typestates
ARG of Max+Library rel acq read Maximal Client Static e=0; Static a=NULL; acq(){ if(a==NULL){ a: =m_new(); } else e: =1; return; } read(){ if(a!=NULL){ a: =m_rd(a); } else e: =1; return; } rel(){ a: =NULL; return; } Library rel a=0, e=0 n 0 rel acq : a=0, e=0 read n 1 n 2 : e=0 acq read Interface !
ARG of Max+Library rel a=0, e=0 Predicate Labels = Typestate Interpretation n 0 rel acq : a=0, e=0 read n 1 n 2 : e=0 acq read Safe, Permissive by construction Interface
Computing Interfaces Problem A: Interface Checking Given Library, candidate interface I, abstraction , Solution: Assertion verification, Abstract Reach. Graph Check if I is safe, permissive. Problem B: Interface Reconstruction Given Library, abstraction Solution: Interface = ARG (w. r. t. , ) of Max Client + Library Reconstruct a safe, permissive interface I. Problem C: Interface Inference Given Library, Infer a safe, permissive interface I.
Computing Interfaces Problem A: Interface Checking Given Library, candidate interface I, abstraction , Solution: Assertion verification, Abstract Reach. Graph Check if I is safe, permissive. Problem B: Interface Reconstruction Given Library, abstraction Solution: Interface = ARG (w. r. t. , ) of Max Client + Library Reconstruct a safe, permissive interface I. Problem C: Interface Inference Given Library, Infer a safe, permissive interface I.
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/x rel/x read write rel/x() acq(){ acqx(){ if(a==NULL){ a: =m_new(); } else e: =1; x: =1; return; } } else e: =1; } read(){ write(){ if(a!=NULL){ if(x!=0){ a: =m_rd(a); m_wr(a); } else e: =1; return; } relx(){ rel(){ a: =NULL; x: =0; } return; } e=0 acq/x() read() write() e=0 Ç : e=0 * Abstract Reach Graph ={e=0}
Example Static e=0, a=NULL, x=0; acq/x rel/x read write acq(){ acqx(){ if(a==NULL){ a: =m_new(); } else e: =1; x: =1; return; } } else e: =1; } read(){ write(){ if(a!=NULL){ if(x!=0){ a: =m_rd(a); m_wr(a); } else e: =1; return; } relx(){ rel(){ a: =NULL; x: =0; } return; } read() e=0 Ç : e=0 Imprecise ! 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/x rel/x read write acq(){ acqx(){ if(a==NULL){ a: =m_new(); } else e: =1; x: =1; return; } } else e: =1; } read(){ write(){ if(a!=NULL){ if(x!=0){ a: =m_rd(a); m_wr(a); } else e: =1; return; } relx(){ rel(){ a: =NULL; x: =0; } return; } rel/x() a=0, e=0 acq /x : e=0 rel /x acq /x : a=0, e=0 : e=0 Ç e=0 write() read() Abstract Reach Graph ={e=0, a=0}
Example Static e=0, a=NULL, x=0; acq/x rel/x read write acq(){ acqx(){ if(a==NULL){ a: =m_new(); } else e: =1; x: =1; return; } } else e: =1; } read(){ write(){ if(a!=NULL){ if(x!=0){ a: =m_rd(a); m_wr(a); } else e: =1; return; } relx(){ rel(){ a: =NULL; x: =0; } return; } acqx() : e=0 Ç e=0 write() 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/x rel/x read write acq(){ acqx(){ if(a==NULL){ a: =m_new(); } else e: =1; x: =1; return; } } else e: =1; } read(){ write(){ if(a!=NULL){ if(x!=0){ a: =m_rd(a); m_wr(a); } else e: =1; return; } relx(){ rel(){ a: =NULL; x: =0; } return; } rel/x() a=0, e=0, x=0 acqx acq : a=0, e=0, x=0 rel /x read() rel /x : e=0 : a=0 , e=0 x=0 write() read() Safe, Permissive Interface
Example rel/x Static e=0, a=NULL, x=0; acq(){ acqx(){ if(a==NULL){ a: =m_new(); } else e: =1; x: =1; return; } } else e: =1; } read(){ write(){ if(a!=NULL){ if(x!=0){ a: =m_rd(a); m_wr(a); } else e: =1; return; } relx(){ rel(){ a: =NULL; x: =0; } return; } rel/x() a=0, e=0, acq x=0 n 0 acqx acq : a=0, e=0, x=0 n 1 acqx relrelx rel /x /x read() n 3 : e=0 , n: 2 a=0 e=0 x=0 write() read() Safe, Permissive Interface
Computing Interfaces Problem A: Interface Checking Given Library, candidate interface I, abstraction , Solution: Assertion verification, Abstract Reach. Graph Check if I is safe, permissive. Problem B: Interface Reconstruction Given Library, abstraction Solution: Interface = ARG (w. r. t. , ) of Max Client + Library Reconstruct a safe, permissive interface I. Problem C: Interface Inference Given Library, Solution: abstraction using imprecise ARG vertices Infer a Refine safe, permissive interface I.
Safety Verification vs Interface Construction 1. Error not reachable 1. Error reachable 2. Show always legal Find one illegal sequence 2. Find all legal sequences Find all illegal sequences 3. Refine: Infeasible path to Error (Safe) OR Infeasible path to Legal (Perm) 5. Refine: Fewer behaviors 5. Refine: More behaviors
Plan 1. Motivation 2. Characterizing Safe, Permissive Interfaces 3. Computing Safe, Permissive Interfaces 4. Extensions 5. Experiments
Extensions: Outputs allow non-determinism in library rel acq, 0 Static e=0; acq(){ Static a=NULL; if (. . . ) return 0; read(){ else { if(a!=NULL){ if(a==NULL){ a: =m_rd(a); a: =m_new(); } else e: =1; return; } return 1; rel(){ } a: =NULL; return; } n 0 acq, 1 read rel n 1 n 2 acq, * read 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 • Find interfaces for Java classes (JDK 1. 4) – – • Input: Class, Error states (Exception raised) Tool Automatically finds predicates, interfaces Classes - – – • Signature, Server. Table. Entry, List. Itr, Socket Private state variables determine interface Partition methods by which variables they affect Socket: 6 Predicates, <30 s connect -> get. Input. Stream -> shut. Down. Input -> 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 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; } 1. Loop Invariants 2. Logical formula 3. Check Validity Invariant: lock Æ new = old Ç : lock Æ new old
Verification by Theorem Proving 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; } 1. Loop Invariants 2. Logical formula 3. Check Validity - Loop Invariants - Multithreaded Programs + Behaviors encoded in logic + Decision Procedures [ESC] Precise
Verification by Program Analysis 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; } 1. Dataflow Facts 2. Constraint System 3. Solve constraints - Imprecision due to fixed facts + Abstraction + Type/Flow Analyses Scalable [CQUAL, ESP, MC]
Verification by Model Checking 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; } 1. (Finite State) Program 2. State Transition Graph 3. Reachability + + Pgm ! Finite state model State explosion State Exploration Counterexamples Precise [SPIN, SMV, Bandera, JPF ]
Combining Strengths Theorem Proving Program Analysis - loop invariants + Behaviors encoded in logic Refine + Theorem provers Computing Successors, Refine Lazy Abstraction - Imprecise + Abstraction Shrink state space Model Checking - Finite-state model, state explosion + State Space Exploration Path Sensitive Analysis + Counterexamples Finding Relevant Facts
Thank you www. cs. uc{sd, la}. edu/~blast/
- Slides: 82