340 likes | 451 Views
Verifying Safety Properties using Separation and Heterogeneous Abstractions. E. Yahav School of Computer Science Tel-Aviv University. G. Ramalingam IBM T.J. Watson Research Center. Verification of Safety Properties. The Canvas Project (IBM Watson and Tel Aviv)
E N D
Verifying Safety Propertiesusing Separationand Heterogeneous Abstractions E. Yahav School of Computer Science Tel-Aviv University G. Ramalingam IBM T.J. Watson Research Center
Verification of Safety Properties The CanvasProject (IBM Watson and Tel Aviv) (Component Annotation, Verification and Stuff) Component a library with cleanly encapsulated state Client a program that uses the library • Lightweight Specification • "correct usage" rules a client must follow • "call open() before read()" Certification does the client program satisfy the lightweight specification?
Quick Overview:Fine Grained Heap Abstraction Heap H Precise ... ... but often too expensive
Fine-grained abstraction Coarse abstraction Quick Overview:Separation & Heterogeneous Abstraction
Separation: The Intuition InputStream ins1 = new InputStream(); InputStream ins2 = new InputStream(); ... if (?) { ins1.close(); ... } if (?) { ins2.close(); ... } … Problem: verify that InputStreams are used correctly: not read after they are closed. • Possible states: • ins1: open; ins2: open • ins1: open; ins2: closed • ins1: closed; ins2: open • ins1: closed; ins2: closed
Separation: The Intuition InputStream ins1 = new InputStream(); InputStream ins2 = new InputStream(); ... if (?) { ins1.close(); ... } if (?) { ins2.close(); ... } … • Sub-problems: • verify that ins1 is used correctly • verify that ins2 is used correctly • Possible states • (sub-problem 1) • ins1: open • ins1: closed • Possible states • (sub-problem 2) • ins2: open • ins2: closed
Separation: The Intuition • Basic idea of separation is not new • independent attribute analysis vs. relational analysis • e.g. conventional (compiler) dataflow analyses • e.g. ESP (PLDI 2002) exploits separation
Our Contribution:Separation + Heap Analysis • Separation for heap analysis integrated with verification • Heterogeneous abstraction for heaps • Separation for first-order safety properties • Separation strategies • More focused separation • individual object vs. allocation-site
Heap (Pointer) Analysis • Dynamic object creation (heap allocation) is the primary source of unbounded program state • Creating a bounded representation of a potentially unbounded heap is a key aspect of program analysis • by merging multiple objects into a “summary” object • e.g., merge all objects allocated at same allocation site into one summary object
A Common Approach to Pointer Analysis in Software Verification • Break verification problem into two phases • Preprocessing phase – separate points-to analysis • typically no distinction between objects allocated at same site • Verification phase – verification using points-to results • May lose precision • May lose ability to perform strong updates • May produce false alarms Pointer Analysis Verification Analysis Program Property
Loss of Precision in Two-Phase Approach Verify f is not read after it is closed f = new InputStream(); f.read(); f.close(); Straightforward ...
Loss of Precision in Two-Phase Approach while (?) { f = new InputStream(); f.read(); f.close(); } f1 f closed False alarm! “read may be erroneous”
The TVLA Approach • TVLA is a flexible (parametric) system for abstract interpretation and verification • parametric heap (i.e., pointer) analysis • user can specify criterion for merging heap-allocated objects • user can specify criterion for merging shape graphs • verification integrated with heap analysis • heap analysis (merging criterion) can adapt to verification Frontend AbstractInterpretation First-OrderTransition Sys Program Property
Concrete States Abstract States f f f closed f closed f closed f closed closed closed closed closed f … The TVLA Approach: An Example while (?) { f = new InputStream(); f.read(); f.close(); }
Fine Grained Heap Abstraction Heap H Precise ... ... but often too expensive
Fine-grained abstraction Coarse abstraction Separation & Heterogeneous Abstraction
Outline of Our Approach • Decompose verification problem into a set of subproblems • Adapt abstraction to each subproblem
Outline of Our Approach • Decompose verification problem into a set of subproblems • Analysis-user specifies a separation strategy • Adapt abstraction to each subproblem • Heterogeneous abstraction
Example – Input Streams InputStream ins1 = getInputStream(); InputStream ins2 = getInputStream(); InputStream ins3 = getInputStream(); InputStream ins4 = getInputStream(); InputStream ins = ins1; if (?) { ins1.close(); ins = ins2; } if (?) { ins2.close(); ins = ins3; } if (?) { ins3.close(); ins = ins4; } int val = ins.read(); …
ins1 ins2 ins3 ins4 ins1 ins2 ins3 ins4 site[1] site[1] site[1] site[1] site[1] ins1 ins2 ins3 ins4 ins2 ins1 ins3 ins4 site[1] site[1] site[1] site[1] ins3 ins1 ins2 ins4 ins4 ins1 ins2 ins3 site[1] site[1] site[1] site[1] Separation Strategies choose some i : InputStream() Abstract state after creation of all four InputStream: (with separation) Without separation Abstraction 1 (expensive) Abstraction 2 (imprecise)
ins1 ins ins2 ins3 ins4 … site[1] site[1] site[1] site[1] ins1 ins ins2 ins3 ins4 closed site[1] … site[1] site[1] site[1] ins1 ins ins2 ins3 ins4 … site[1] site[1] site[1] site[1] ins1 ins ins2 ins3 ins4 closed site[1] … site[1] site[1] site[1] … ins1 ins2 ins3 ins ins4 closed site[1] closed site[1] closed site[1] … site[1] Example – Input Streams InputStream ins1 = getInputStream(); InputStream ins2 = getInputStream(); InputStream ins3 = getInputStream(); InputStream ins4 = getInputStream(); InputStream ins = ins1; if (?) { ins1.close(); ins = ins2; } if (?) { ins2.close(); ins = ins3; } if (?) { ins3.close(); ins = ins4; } int val = ins.read(); …
Example – Input Streams InputStream ins1 = getInputStream(); InputStream ins2 = getInputStream(); InputStream ins3 = getInputStream(); InputStream ins4 = getInputStream(); InputStream ins = ins1; if (?) { ins1.close(); ins = ins2; } if (?) { ins2.close(); ins = ins3; } if (?) { ins3.close(); ins = ins4; } int val = ins.read(); … ins1 ins ins2 ins3 ins4 site[1] site[1] ins1 ins ins2 ins3 ins4 closed site[1] site[1] ins1 ins ins2 ins3 ins4 site[1] site[1] ins1 ins ins2 ins3 ins4 closed = 1/2 site[1] site[1] ins1 ins2 ins3 ins ins4 closed=1/2 site[1] closed site[1]
First-Order Safety Properties • Involve multiple correlated objects • e.g., JDBC • Problem can be decomposed into sub-problems in several different ways • Different separation granularity • Different efficiency, different precision ... ResultSet rs2 = stmt2.executeQuery(...); ... ResultSet minRs2 = stmt2.executeQuery(...) ... rs2.next();
Example: JDBC Specification class ResultSet { boolean closed; Statement ownerStmt; ResultSet(Statement s) { closed = false ; ownerStmt = s; } void close() { closed = true; } boolean next() { requires !closed; } } Class Connection { Set statements; … } class Statement { boolean closed; ResultSet myResultSet; Connection myConnection; Statement(Connection c) { closed = false; myConnection = c; myResultSet = null; } ResultSet executeQuery(String qry) { requires !closed; if (myResultSet != null) myResultSet.closed = true; myResultSet = new ResultSet(this); return myResultSet; } … }
Single Choice Separation choose some c : Connection() choose all s : Statement(x) / x == c choose all r : ResultSet(y) / y == s con1 stmt1 rs1 con2 stmt2 minRs2 myRS myRS stmt stmt own own own own own maxRs2 maxRs rs2 con1 stmt1 rs1 con2 stmt2 minRs2 myRS myRS stmt stmt own own own own own maxRs2 maxRs rs2
Multiple Choice Separation choose some c : Connection() choose some s : Statement(x) / x == c choose some r : ResultSet(y) / y == s con1 stmt1 rs1 con2 stmt2 minRs2 myRS myRS stmt stmt own own own own own maxRs2 maxRs rs2 con1 stmt1 rs1 con2 stmt2 minRs2 myRS myRS stmt stmt + 6 more own own own own own maxRs2 maxRs rs2
Strategy Implementation • separation strategy + program + property • compiled into TVLA input • using instrumentation predicates • details in paper
Prototype Implementation • Implemented over TVLA • Applied to several example programs • Up to 5000 lines of Java • Used to verify • Absence of concurrent modification exception (CME) • JDBC API conformance • IOStreams API conformance • Improved performance • In some cases improved precision
Other Issues • Objects chosen for verification • Objects relevant for verification (for chosen object) • Identified via reachability • User hints via separation strategy
Related Work • Demand-driven analysis • hard for heap analysis • Program slicing • an approach to demand-driven analysis • simple slicing can be an effective optimization • precise slicing (for heap) is hard • Client-driven pointer analysis (Guyer & Lin, SAS 2003) • Counter-example guided abstraction refinement
Verification: Recent Work • ESC/Modula-3, ESC/Java (CC ’98, ...) • MC (OSDI 2000, ...) • Bandera (ICSE 2000, ...) • SLAM (SPIN 2001, ...) • Vault (PLDI 2001, ...) • BLAST (POPL 2002, ...) • ESP (PLDI 2002, ...) • Foster, Terauchi and Aiken (PLDI 2002, ...) • ... several others ...
It is of highest importance ... to be able to recognize out of a number of facts which are incidental and which vital... Otherwise your energy and attention must be dissipated instead of being concentrated. Arthur Conan Doyle The End Some tasks are best done by machine, while others are best done by human insight; and a properly designed system will find the right balance. D. Knuth