Program Verification by Lazy Abstraction

Slides:



Advertisements
Similar presentations
Automated Theorem Proving Lecture 1. Program verification is undecidable! Given program P and specification S, does P satisfy S?
Advertisements

SAT Based Abstraction/Refinement in Model-Checking Based on work by E. Clarke, A. Gupta, J. Kukula, O. Strichman (CAV’02)
Automatic Verification Book: Chapter 6. What is verification? Traditionally, verification means proof of correctness automatic: model checking deductive:
50.530: Software Engineering Sun Jun SUTD. Week 10: Invariant Generation.
Rigorous Software Development CSCI-GA Instructor: Thomas Wies Spring 2012 Lecture 13.
Introducing BLAST Software Verification John Gallagher CS4117.
Software Verification with BLAST Tom Henzinger Ranjit Jhala Rupak Majumdar.
Proofs and Counterexamples Rupak Majumdar. In the good old days… Decision Procedure  yes no.
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.
SAT and Model Checking. Bounded Model Checking (BMC) A.I. Planning problems: can we reach a desired state in k steps? Verification of safety properties:
The Software Model Checker BLAST by Dirk Beyer, Thomas A. Henzinger, Ranjit Jhala and Rupak Majumdar Presented by Yunho Kim Provable Software Lab, KAIST.
Thread-modular Abstraction Refinement Tom Henzinger Ranjit Jhala Rupak Majumdar Shaz Qadeer.
Using Statically Computed Invariants Inside the Predicate Abstraction and Refinement Loop Himanshu Jain Franjo Ivančić Aarti Gupta Ilya Shlyakhter Chao.
Software Verification with Blast Thomas A. Henzinger, Ranjit Jhala, Rupak Majumdar, George Necula, Grégoire Sutre, Wes Weimer UC Berkeley.
Scalable Program Verification by Lazy Abstraction Ranjit Jhala U.C. Berkeley.
Lazy Abstraction Thomas A. Henzinger Ranjit Jhala Rupak Majumdar Grégoire Sutre UC Berkeley.
Recap from last time We were trying to do Common Subexpression Elimination Compute expressions that are available at each program point.
Program Verification by Lazy Abstraction Ranjit Jhala UC San Diego Lecture 1 With: Tom Henzinger, Rupak Majumdar, Ken McMillan, Gregoire Sutre.
ESC Java. Static Analysis Spectrum Power Cost Type checking Data-flow analysis Model checking Program verification AutomatedManual ESC.
Thread-modular Abstraction Refinement Tom Henzinger Ranjit Jhala Rupak Majumdar [UC Berkeley] Shaz Qadeer [Microsoft Research]
Lazy Predicate Abstraction in BLAST John Gallagher CS4117.
SLAM Over the Summer Wes Weimer (Tom Ball, Sriram Rajamani, Manuvir Das)
An Evaluation of BLAST John Gallagher CS4117. Overview BLAST incorporates new, fascinating and complex technology. The engine and external components.
Speeding Up Dataflow Analysis Using Flow- Insensitive Pointer Analysis Stephen Adams, Tom Ball, Manuvir Das Sorin Lerner, Mark Seigle Westley Weimer Microsoft.
Counter Example Guided Refinement CEGAR Mooly Sagiv.
CS 267: Automated Verification Lectures 14: Predicate Abstraction, Counter- Example Guided Abstraction Refinement, Abstract Interpretation Instructor:
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.
Software Reliability Methods Sorin Lerner. Software reliability methods: issues What are the issues?
Temporal-Safety Proofs for Systems Code Thomas A. Henzinger Ranjit Jhala Rupak Majumdar George Necula Westley Weimer Grégoire Sutre UC Berkeley.
ESC Java. Static Analysis Spectrum Power Cost Type checking Data-flow analysis Model checking Program verification AutomatedManual ESC.
Lazy Abstraction with Interpolants Yakir Vizel (based on the work and slides of K. L. McMillan at CAV06)
Software Verification with BLAST Tom Henzinger Ranjit Jhala Rupak Majumdar.
Lazy Abstraction Lecture 2: Modular Analyses Ranjit Jhala UC San Diego With: Tom Henzinger, Rupak Majumdar, Ken McMillan, Gregoire Sutre.
Lazy Abstraction Tom Henzinger Ranjit Jhala Rupak Majumdar Grégoire Sutre.
CS 267: Automated Verification Lecture 13: Bounded Model Checking Instructor: Tevfik Bultan.
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.
Program Verification by Lazy Abstraction Ranjit Jhala UC San Diego Lecture 1 With: Tom Henzinger, Rupak Majumdar, Ken McMillan, Gregoire Sutre, Adam Chlipala.
272: Software Engineering Fall 2012 Instructor: Tevfik Bultan Lecture 4: SMT-based Bounded Model Checking of Concurrent Software.
Thread-modular Abstraction Refinement Thomas A. Henzinger, et al. CAV 2003 Seonggun Kim KAIST CS750b.
Languages of nested trees Swarat Chaudhuri University of Pennsylvania (with Rajeev Alur and P. Madhusudan)
Race Checking by Context Inference Tom Henzinger Ranjit Jhala Rupak Majumdar UC Berkeley.
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.
Lazy Annotation for Program Testing and Verification Speaker: Chen-Hsuan Adonis Lin Advisor: Jie-Hong Roland Jiang November 26,
Localization and Register Sharing for Predicate Abstraction Himanshu Jain Franjo Ivančić Aarti Gupta Malay Ganai.
SMT and Its Application in Software Verification (Part II) Yu-Fang Chen IIS, Academia Sinica Based on the slides of Barrett, Sanjit, Kroening, Rummer,
Ranjit Jhala Rupak Majumdar Interprocedural Analysis of Asynchronous Programs.
CS357 Lecture 13: Symbolic model checking without BDDs Alex Aiken David Dill 1.
Counter Example Guided Refinement CEGAR Mooly Sagiv.
#1 Having a BLAST with SLAM. #2 Software Model Checking via Counter-Example Guided Abstraction Refinement Topic: Software Model Checking via Counter-Example.
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.
Having a BLAST with SLAM
Program Analysis via Satisfiability Modulo Path Programs
Input Space Partition Testing CS 4501 / 6501 Software Testing
Reasoning About Code.
Reasoning about code CSE 331 University of Washington.
Automatic Verification
Lifting Propositional Interpolants to the Word-Level
CSCI1600: Embedded and Real Time Software
Abstractions from Proofs
Abstraction, Verification & Refinement
The Zoo of Software Security Techniques
Software Verification with BLAST
Predicate Abstraction
BLAST: A Software Verification Tool for C programs
COP4020 Programming Languages
SAT Based Abstraction/Refinement in Model-Checking
Presentation transcript:

Program Verification by Lazy Abstraction Lecture 1 Ranjit Jhala UC San Diego With: Tom Henzinger, Rupak Majumdar, Ken McMillan, Gregoire Sutre, Adam Chlipala

Software Validation Large scale reliable software is hard to build and test Different groups write different components Integration testing is a nightmare

Property Checking Programmer gives partial specifications Code checked for consistency w/ spec Different from program correctness Specifications are not complete Is there a complete spec for Word ? Emacs ?

Interface Usage Rules Rules in documentation Order of operations & data access Resource management Incomplete, unenforced, wordy Violated rules ) bad behavior System crash or deadlock Unexpected exceptions Failed runtime checks

Property 1: Double Locking unlock “An attempt to re-acquire an acquired lock or release a released lock will cause a deadlock.” Calls to lock and unlock must alternate.

Property 2: Drop Root Privilege [Chen-Dean-Wagner ’02] “User applications must not run with root privilege” When execv is called, must have suid  0

Property 3 : IRP Handler [Fahndrich] MPR3 CallDriver MPR completion synch not pending returned SKIP2 IPC Skip return child status DC Complete request not Pend PPC prop N/A no prop start NP Pending NP MPR1 start P Mark Pending IRP accessible SKIP1 MPR2 [Fahndrich]

Does a given usage rule hold? Undecidable! Equivalent to the halting problem Restricted computable versions are prohibitively expensive (PSPACE) Why bother ? Just because a problem is undecidable, it doesn’t go away! May be do this through an example

Example 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; lock unlock

What a program really is… State Transition pc lock old new q  3   5  0x133a 3: unlock(); new++; 4:} … pc lock old new q  4   5  6  0x133a 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;}

The Safety Verification Problem Error Safe Initial Is there a path from an initial to an error state ? Problem: Infinite state graph Solution : Set of states ' logical formula

Representing States as Formulas states satisfying F {s | s ² F } F FO fmla over prog. vars [F1] Å [F2] F1 Æ F2 [F1] [ [F2] F1 Ç F2 May be do this through an example [F] : F [F1] µ [F2] F1 implies F2 i.e. F1Æ: F2 unsatisfiable

Idea 1: Predicate Abstraction Predicates on program state: lock old = new States satisfying same predicates are equivalent Merged into one abstract state #abstract states is finite

Abstract States and Transitions pc lock old new q  3   5  0x133a 3: unlock(); new++; 4:} … pc lock old new q  4   5  6  0x133a Theorem Prover lock old=new : lock : old=new

Abstraction State Existential Lifting Theorem Prover lock : lock pc lock old new q  3   5  0x133a 3: unlock(); new++; 4:} … pc lock old new q  4   5  6  0x133a Theorem Prover lock old=new : lock : old=new Existential Lifting

Abstraction State lock : lock old=new : old=new 3: unlock(); new++; pc lock old new q  3   5  0x133a 3: unlock(); new++; 4:} … pc lock old new q  4   5  6  0x133a lock old=new : lock : old=new

Analyze Abstraction Problem Analyze finite graph No false negatives Over Approximate: Safe ) System Safe No false negatives Problem Spurious counterexamples

Idea 2: Counterex.-Guided Refinement Solution Use spurious counterexamples to refine abstraction !

Idea 2: Counterex.-Guided Refinement Solution Use spurious counterexamples to refine abstraction 1. Add predicates to distinguish states across cut 2. Build refined abstraction Imprecision due to merge

Iterative Abstraction-Refinement Solution Use spurious counterexamples to refine abstraction 1. Add predicates to distinguish states across cut 2. Build refined abstraction -eliminates counterexample 3. Repeat search Till real counterexample or system proved safe [Kurshan et al 93] [Clarke et al 00] [Ball-Rajamani 01]

Lazy Abstraction BLAST Safe Abstract Refine Trace Yes C Program No Property Trace

Problem: Abstraction is Expensive Reachable Problem #abstract states = 2#predicates Exponential Thm. Prover queries Observe Fraction of state space reachable #Preds ~ 100’s, #States ~ 2100 , #Reach ~ 1000’s

Solution1: Only Abstract Reachable States Safe Solution Build abstraction during search Problem #abstract states = 2#predicates Exponential Thm. Prover queries

Solution2: Don’t Refine Error-Free Regions Problem #abstract states = 2#predicates Exponential Thm. Prover queries Solution Don’t refine error-free regions

Key Idea: Reachability Tree Initial Unroll Abstraction 1. Pick tree-node (=abs. state) 2. Add children (=abs. successors) 3. On re-visiting abs. state, cut-off 1 2 3 Find min infeasible suffix - Learn new predicates - Rebuild subtree with new preds. 4 5 3

Key Idea: Reachability Tree Initial Unroll Abstraction 1. Pick tree-node (=abs. state) 2. Add children (=abs. successors) 3. On re-visiting abs. state, cut-off 1 2 3 6 Find min infeasible suffix - Learn new predicates - Rebuild subtree with new preds. 4 5 7 3 3 Error Free

Key Idea: Reachability Tree Initial Unroll 1. Pick tree-node (=abs. state) 2. Add children (=abs. successors) 3. On re-visiting abs. state, cut-off 1 2 3 6 Find min spurious suffix - Learn new predicates - Rebuild subtree with new preds. 4 5 7 8 3 3 1 8 1 Error Free S1: Only Abstract Reachable States S2: Don’t refine error-free regions SAFE

Build-and-Search Reachability Tree Predicates: LOCK 1 1 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 (); 1 : LOCK 1 Reachability Tree Predicates: LOCK

Build-and-Search Reachability Tree Predicates: LOCK 1 2 1 2 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 (); lock() old = new q=q->next 1 : LOCK 2 LOCK 1 2 Reachability Tree Predicates: LOCK

Build-and-Search Reachability Tree Predicates: LOCK 1 2 3 1 2 3 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 (); 1 : LOCK 2 LOCK [q!=NULL] 3 LOCK 1 2 3 Reachability Tree Predicates: LOCK

Build-and-Search Reachability Tree Predicates: LOCK 1 2 3 4 4 1 2 3 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 (); 1 : LOCK 2 LOCK 3 q->data = new unlock() new++ LOCK 4 : LOCK 4 1 2 3 Reachability Tree Predicates: LOCK

Build-and-Search Reachability Tree Predicates: LOCK 1 2 3 4 5 5 4 1 2 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 (); 1 : LOCK 2 LOCK 3 LOCK 4 : LOCK [new==old] 5 : LOCK 5 4 1 2 3 Reachability Tree Predicates: LOCK

Build-and-Search Reachability Tree Predicates: LOCK 1 2 3 4 5 5 4 1 2 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 (); 1 : LOCK 2 LOCK 3 LOCK 4 : LOCK 5 : LOCK 5 unlock() 4 : LOCK 1 2 3 Reachability Tree Predicates: LOCK

Analyze Counterexample 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); 1 : LOCK lock() old = new q=q->next 2 LOCK [q!=NULL] 3 LOCK q->data = new unlock() new++ 4 : LOCK [new==old] 5 : LOCK 5 unlock() 4 : LOCK 1 2 3 Reachability Tree Predicates: LOCK

Analyze Counterexample 1: do{ lock(); old = new; q = q->next; 2: if (q != NULL){ 3: q->data = new; unlock(); new ++; } 4:}while(new != old); 5: unlock (); 1 : LOCK old = new 2 LOCK 3 LOCK new++ 4 : LOCK [new==old] 5 : LOCK 5 Inconsistent 4 : LOCK new == old 1 2 3 Reachability Tree Predicates: LOCK

Repeat Build-and-Search 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 (); 1 : LOCK 1 Reachability Tree Predicates: LOCK, new==old

Repeat Build-and-Search 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 (); 1 : LOCK lock() old = new q=q->next 2 LOCK , new==old 1 2 Reachability Tree Predicates: LOCK, new==old

Repeat Build-and-Search 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 (); 1 : LOCK 2 LOCK , new==old LOCK , new==old 3 q->data = new unlock() new++ 4 : LOCK , : new = old 4 1 2 3 Reachability Tree Predicates: LOCK, new==old

Repeat Build-and-Search 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 (); 1 : LOCK 2 LOCK , new==old LOCK , new==old 3 4 : LOCK , : new = old [new==old] 4 1 2 3 Reachability Tree Predicates: LOCK, new==old

Repeat Build-and-Search 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 (); 1 : LOCK 2 LOCK , new==old LOCK , new==old 3 4 : LOCK , : new = old [new!=old] 1 : LOCK, : new == old 4 4 1 2 3 Reachability Tree Predicates: LOCK, new==old

Repeat Build-and-Search 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 (); 1 : LOCK 2 LOCK , new==old SAFE LOCK , new==old 3 4 4 : LOCK , : new = old LOCK , new=old 1 5 5 : LOCK, : new == old 4 4 4 1 : LOCK , new==old 2 3 Reachability Tree Predicates: LOCK, new==old

Key Idea: Reachability Tree Initial Unroll 1. Pick tree-node (=abs. state) 2. Add children (=abs. successors) 3. On re-visiting abs. state, cut-off 1 2 3 6 Find min spurious suffix - Learn new predicates - Rebuild subtree with new preds. 4 5 7 8 3 3 1 8 1 Error Free S1: Only Abstract Reachable States S2: Don’t refine error-free regions SAFE

Two handwaves SAFE Reachability Tree Predicates: LOCK, new==old 1 2 3 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 (); 1 : LOCK 2 LOCK , new==old SAFE LOCK , new==old 3 4 4 : LOCK , : new = old LOCK , new=old 1 5 5 : LOCK, : new == old 4 4 4 1 : LOCK , new==old 2 3 Reachability Tree Predicates: LOCK, new==old

Two handwaves SAFE Q. How to compute “successors” ? Reachability Tree 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 (); 1 : LOCK Q. How to compute “successors” ? 2 LOCK , new==old SAFE LOCK , new==old 3 LOCK , new==old 3 q->data = new unlock() new++ 4 4 4 : LOCK , : new = old : LOCK , : new = old LOCK , new=old 1 5 5 : LOCK, : new == old 4 4 4 1 : LOCK , new==old 2 3 Reachability Tree Predicates: LOCK, new==old

Two handwaves SAFE Q. How to compute “successors” ? 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 (); 1 : LOCK Q. How to compute “successors” ? 2 LOCK , new==old SAFE LOCK , new==old 3 4 4 : LOCK , : new = old LOCK , new=old Q. How to find predicates ? 1 5 5 Refinement : LOCK, : new == old 4 4 4 1 : LOCK , new==old 2 3 Predicates: LOCK, new==old

Two handwaves SAFE Q. How to compute “successors” ? Refinement 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 (); 1 : LOCK Q. How to compute “successors” ? 2 LOCK , new==old SAFE LOCK , new==old 3 4 4 : LOCK , : new = old LOCK , new=old 1 5 5 Refinement : LOCK, : new == old 4 4 4 1 : LOCK , new==old 2 3 Predicates: LOCK, new==old

Weakest Preconditions WP(P,OP) Weakest formula P’ s.t. if P’ is true before OP then P is true after OP [WP(P, OP)] OP [P]

Weakest Preconditions WP(P,OP) Weakest formula P’ s.t. if P’ is true before OP then P is true after OP [WP(P, OP)] OP [P] P[e/x] new+1 = old Assign new = new+1 x = e P new = old

Weakest Preconditions WP(P,OP) Weakest formula P’ s.t. if P’ is true before OP then P is true after OP [WP(P, OP)] OP [P] c ) P new=old ) new=old Assume Branch [new=old] [c] P new = old

How to compute successor ? 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 (); LOCK , new==old 3 F OP 4 ? : LOCK , : new = old For each p Check if p is true (or false) after OP Q: When is p true after OP ? - If WP(p, OP) is true before OP ! - We know F is true before OP - Thm. Pvr. Query: F ) WP(p, OP) Predicates: LOCK, new==old

How to compute successor ? 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 (); LOCK , new==old 3 F OP 4 ? For each p Check if p is true (or false) after OP Q: When is p false after OP ? - If WP(: p, OP) is true before OP ! - We know F is true before OP - Thm. Pvr. Query: F ) WP(: p, OP) Predicates: LOCK, new==old

How to compute successor ? 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 (); LOCK , new==old 3 F OP 4 ? : new = old : LOCK , : new = old For each p Check if p is true (or false) after OP Q: When is p false after OP ? - If WP(: p, OP) is true before OP ! - We know F is true before OP - Thm. Pvr. Query: F ) WP(: p, OP) Predicate: new==old True ? (LOCKÆ new==old) ) (new + 1 = old) NO False ? (LOCKÆ new==old) ) (new + 1  old) YES

Lazy Abstraction Problem: Abstraction is Expensive Yes Safe C Program Abstract Refine No Property Trace Problem: Abstraction is Expensive Solution: 1. Abstract reachable states, 2. Avoid refining error-free regions Key Idea: Reachability Tree

Property: IRP Handler [Fahndrich] MPR3 CallDriver MPR completion synch not pending returned SKIP2 IPC Skip return child status DC Complete request not Pend PPC prop N/A no prop start NP Pending NP MPR1 start P Mark Pending IRP accessible SKIP1 MPR2 [Fahndrich]

Results Program kbfiltr 12k 1 34 floppy 17k 7 93 diskprf 14k 5 71 Property3: IRP Handler Win NT DDK Results Program Lines* Time(mins) Predicates kbfiltr 12k 1 34 floppy 17k 7 93 diskprf 14k 5 71 cdaudio 18k 20 85 parport 61k DNF parclss 138k * Pre-processed

#Predicates grows with program size while(1){ 1: if (p1) lock() ; if (p1) unlock() ; … 2: if (p2) lock() ; if (p2) unlock() ; n: if (pn) lock() ; if (pn) unlock() ; } T F Tracking lock not enough Problem: p1,…,pn needed for verification Exponential reachable abstract states

#Predicates grows with program size while(1){ 1: if (p1) lock() ; if (p1) unlock() ; … 2: if (p2) lock() ; if (p2) unlock() ; n: if (pn) lock() ; if (pn) unlock() ; } : LOCK LOCK, p1 : LOCK, : p1 : LOCK, p1 : LOCK, : p1 : LOCK p1p2 p1: p2 : p1 p2 : p1: p2 2n Abstract States Problem: p1,…,pn needed for verification Exponential reachable abstract states

Predicates useful locally while(1){ 1: if (p1) lock() ; if (p1) unlock() ; … 2: if (p2) lock() ; if (p2) unlock() ; n: if (pn) lock() ; if (pn) unlock() ; } : LOCK p1 LOCK , p1 : LOCK, : p1 : LOCK , p1 : LOCK : LOCK : LOCK : LOCK , : p1 LOCK , p2 : LOCK , : p2 : LOCK p2 pn 2n Abstract States Solution: Use predicates only where needed Using Counterexamples: Q1. Find predicates Q2. Find where predicates are needed

Lazy Abstraction Safe Abstract Refine Trace Yes Safe C Program Abstract Refine No Property Trace Problem: #Preds grows w/ Program Size Solution: Localize pred. use, find where preds. needed Ctrex. Trace Pred. Map PC  Preds. Refine

Counterexample Traces 1: x = ctr; 2: ctr = ctr + 1; 3: y = ctr; 4: if (x = i-1){ 5: if (y != i){ ERROR: } } 1: x = ctr 2: ctr = ctr + 1 3: y = ctr 4: assume(x = i-1) 5: assume(y  i) y = x +1

Trace Formulas Thm: Trace is feasible , TF is satisfiable Trace 1: x = ctr 2: ctr = ctr+1 3: y = ctr 4: assume(x=i-1) 5: assume(yi) 1: x1 = ctr0 2: ctr1 = ctr0+1 3: y1 = ctr1 4: assume(x1=i0-1) 5: assume(y1i0) x1 = ctr0 Æ ctr1 = ctr0+ 1 Æ y1 = ctr1 Æ x1 = i0 - 1 Æ y1  i0 Trace SSA Trace Trace Feasibility Formula Thm: Trace is feasible , TF is satisfiable

The Present State… … is all the information the Trace 1: x = ctr 2: ctr = ctr + 1 3: y = ctr 4: assume(x = i-1) 5: assume(y  i) … is all the information the executing program has here State… 1. … after executing trace past (prefix) 2. … knows present values of variables 3. … makes trace future (suffix) infeasible At pc4, which predicate on present state shows infeasibility of future ?

What Predicate is needed ? Trace Trace Formula (TF) 1: x = ctr 2: ctr = ctr + 1 3: y = ctr 4: assume(x = i-1) 5: assume(y  i) x1 = ctr0 Æ ctr1 = ctr0 +1 Æ y1 = ctr1 Æ x1 = i0 - 1 Æ y1  i0

What Predicate is needed ? Trace Trace Formula (TF) 1: x = ctr 2: ctr = ctr + 1 3: y = ctr 4: assume(x = i-1) 5: assume(y  i) x1 = ctr0 Æ ctr1 = ctr0+ 1 Æ y1 = ctr1 Æ x1 = i0 - 1 Æ y1  i0 Relevant Information Predicate … 1. … after executing trace prefix … implied by TF prefix

What Predicate is needed ? Trace Trace Formula (TF) 1: x = ctr 2: ctr = ctr + 1 3: y = ctr 4: assume(x = i-1) 5: assume(y  i) x1 = ctr0 Æ ctr1 = ctr0+ 1 Æ y1 = ctr1 Æ x1 = i0 - 1 Æ y1  i0 x1 x1 Relevant Information Predicate … 1. … after executing trace prefix 2. … has present values of variables … implied by TF prefix … on common variables

What Predicate is needed ? Trace Trace Formula (TF) 1: x = ctr 2: ctr = ctr + 1 3: y = ctr 4: assume(x = i-1) 5: assume(y  i) x1 = ctr0 Æ ctr1 = ctr0+ 1 Æ y1 = ctr1 Æ x1 = i0 - 1 Æ y1  i0 Relevant Information Predicate … 1. … after executing trace prefix 2. … has present values of variables 3. … makes trace suffix infeasible … implied by TF prefix … on common variables … & TF suffix is unsatisfiable

What Predicate is needed ? Trace Trace Formula (TF) 1: x = ctr 2: ctr = ctr + 1 3: y = ctr 4: assume(x = i-1) 5: assume(y  i) x1 = ctr0 Æ ctr1 = ctr0+ 1 Æ y1 = ctr1 Æ x1 = i0 - 1 Æ y1  i0 Relevant Information Predicate … 1. … after executing trace prefix 2. … has present values of variables 3. … makes trace suffix infeasible … implied by TF prefix … on common variables … & TF suffix is unsatisfiable

Interpolant = Predicate ! Trace Trace Formula 1: x = ctr 2: ctr = ctr + 1 3: y = ctr 4: assume(x = i-1) 5: assume(y  i) x1 = ctr0 Æ ctr1 = ctr0+ 1 Æ y1 = ctr1 Æ x1 = i0 - 1 Æ y1  i0 Predicate at 4: y= x+1 - Interpolate  + y1 = x1 + 1 Craig Interpolant [Craig 57] Computable from Proof of Unsat [Krajicek 97] [Pudlak 97] Predicate … … implied by TF prefix … on common variables … & TF suffix is unsatisfiable

Another interpretation … Trace Formula x1 = ctr0 Æ ctr1 = ctr0+ 1 Æ y1 = ctr1 Æ x1 = i0 - 1 Æ y1  i0 Predicate at 4: y= x+1 After exec prefix - -  Interpolate  Can exec suffix + + y1 = x1 + 1 Unsat = Empty Intersection = Trace Infeasible Interpolant  = Overapproximate states after prefix That cannot execute suffix

Interpolant = Predicate ! Trace Trace Formula 1: x = ctr 2: ctr = ctr + 1 3: y = ctr 4: assume(x = i-1) 5: assume(y  i) x1 = ctr0 Æ ctr1 = ctr0+ 1 Æ y1 = ctr1 Æ x1 = i0 - 1 Æ y1  i0 Predicate at 4: y= x+1 - Interpolate  + y1 = x1 + 1 Craig Interpolant [Craig 57] Computable from Proof of Unsat [Krajicek 97] [Pudlak 97] Predicate … … implied by TF prefix … on common variables … & TF suffix is unsatisfiable

Interpolant = Predicate ! Trace Trace Formula 1: x = ctr 2: ctr = ctr + 1 3: y = ctr 4: assume(x = i-1) 5: assume(y  i) x1 = ctr0 Æ ctr1 = ctr0+ 1 Æ y1 = ctr1 Æ x1 = i0 - 1 Æ y1  i0 Predicate at 4: y= x+1 - Interpolate Q. How to compute interpolants ? …  + y1 = x1 + 1 Craig Interpolant [Craig 57] Computable from Proof of Unsat [Krajicek 97] [Pudlak 97] Predicate … … implied by TF prefix … on common variables … & TF suffix is unsatisfiable

Building Predicate Maps 2: x= ctr Trace Trace Formula - 1: x = ctr 2: ctr = ctr + 1 3: y = ctr 4: assume(x = i-1) 5: assume(y  i) x1 = ctr0 Æ ctr1 = ctr0+ 1 Æ y1 = ctr1 Æ x1 = i0 - 1 Æ y1  i0 Interpolate x1 = ctr0 + Cut + Interpolate at each point Pred. Map: pci  Interpolant from cut i

Building Predicate Maps 2: x = ctr 3: x= ctr-1 Trace Trace Formula 1: x = ctr 2: ctr = ctr + 1 3: y = ctr 4: assume(x = i-1) 5: assume(y  i) x1 = ctr0 Æ ctr1 = ctr0+ 1 Æ y1 = ctr1 Æ x1 = i0 - 1 Æ y1  i0 - Interpolate + x1= ctr1-1 Cut + Interpolate at each point Pred. Map: pci  Interpolant from cut i

Building Predicate Maps 2: x = ctr 3: x= ctr - 1 4: y= x + 1 Trace Trace Formula 1: x = ctr 2: ctr = ctr + 1 3: y = ctr 4: assume(x = i-1) 5: assume(y  i) x1 = ctr0 Æ ctr1 = ctr0+ 1 Æ y1 = ctr1 Æ x1 = i0 - 1 Æ y1  i0 - + Interpolate y1= x1+1 Cut + Interpolate at each point Pred. Map: pci  Interpolant from cut i

Building Predicate Maps 2: x = ctr 3: x= ctr - 1 4: y= x + 1 5: y = i Trace Trace Formula 1: x = ctr 2: ctr = ctr + 1 3: y = ctr 4: assume(x = i-1) 5: assume(y  i) x1 = ctr0 Æ ctr1 = ctr0+ 1 Æ y1 = ctr1 Æ x1 = i0 - 1 Æ y1  i0 - + Interpolate y1= i0 Cut + Interpolate at each point Pred. Map: pci  Interpolant from cut i

Local Predicate Use Verification scales … Use predicates needed at location #Preds. grows with program size #Preds per location small Predicate Map 2: x = ctr 3: x= ctr - 1 4: y= x + 1 5: y = i Verification scales … Local Predicate use Ex: 2n states Global Predicate use Ex: 2n states

Results Program kbfiltr 12k 1 3 72 6.5 floppy 17k 7 25 240 7.7 diskprf Property3: IRP Handler Win NT DDK Results Program Lines* Previous Time(mins) Time (mins) Predicates Total Average kbfiltr 12k 1 3 72 6.5 floppy 17k 7 25 240 7.7 diskprf 14k 5 13 140 10 cdaudio 18k 20 23 256 7.8 parport 61k DNF 74 753 8.1 parclss 138k 77 382 7.2 * Pre-processed

Localizing Program kbfiltr 12k 1 3 72 6.5 floppy 17k 7 25 240 7.7 Property3: IRP Handler Win NT DDK Localizing Program Lines* Previous Time(mins) Time (mins) Predicates Total Average kbfiltr 12k 1 3 72 6.5 floppy 17k 7 25 240 7.7 diskprf 14k 5 13 140 10 cdaudio 18k 20 23 256 7.8 parport 61k DNF 74 753 8.1 parclss 138k 77 382 7.2 * Pre-processed

Q. How to compute interpolants ?

Proof of Unsatisfiability x1 = ctr0 Æ ctr1 = ctr0 + 1 Æ y1 = ctr1 Æ x1 = i0 - 1 Æ y1  i0 x1 = ctr0 x1 = i0 -1 ctr0 = i0-1 ctr1= ctr0+1 ctr1 = i0 y1= ctr1 y1= i0 y1 i0 ; Trace Formula Proof of Unsatisfiability

Another Proof of Unsatisfiability £ (-1) £ 1 x1 = ctr0 x1 = i0 -1 ctr0 = i0-1 ctr1= ctr0+1 ctr1 = i0 y1= ctr1 y1= i0 y1 i0 ; Proof of Unsatisfiability x1– ctr0=0 x1-i0 +1=0 £ 1 ctr0-i0+1=0 ctr1- ctr0-1=0 £ 1 ctr1-i0 =0 y1-ctr1=0 £ 1 y1-i0=0 y1-i0 0 0 0 Rewritten Proof

Interpolant from Rewritten Proof ? £ (-1) £ 1 x1 = ctr0 Æ ctr1 = ctr0 + 1 Æ y1 = ctr1 Æ x1 = i0 - 1 Æ y1  i0 x1– ctr0=0 x1-i0 +1=0 £ 1 ctr0-i0+1=0 ctr1- ctr0-1=0 £ 1 ctr1-i0 =0 y1-ctr1=0 Interpolate £ 1 y1-i0=0 y1-i0 0 0 0 Trace Formula Rewritten Proof

Interpolant from Rewritten Proof ? x1 = ctr0 Æ ctr1 = ctr0 + 1 Æ y1 = ctr1 Æ x1 = i0 - 1 Æ y1  i0 x1– ctr0=0 £ (-1) ctr1- ctr0-1=0 £ 1 y1-ctr1=0 £ 1 Interpolate y1-x1-1=0 y1=x1+1 Trace Formula Interpolant !

Lazy Abstraction Safe Abstract Refine Trace Yes Safe C Program Abstract Refine No Property Trace Problem: #Preds grows w/ Program Size Solution: Localize pred. use, find where preds. needed Refine Trace Feas Formula Ctrex. Trace Proof of Unsat Pred. Map PC  Preds. Thm Pvr Interpolate

Recap … Lazy Abstraction for Sequential Programs Predicates: Abstract infinite program states Counterexample-guided Refinement: Find predicates tailored to prog, property Abstraction : Expensive Reachability Tree Refinement : Find predicates, use locations Proof of unsat of TF + Interpolation

A Choice Procedure Summaries Finish

Next: Modular Lazy Abstraction Using Procedure Summaries

An example main(){  1: if (flag){ 2: y = inc(x,flag); 3: if (y<=x) ERROR; } else { 4: y = inc(z,flag); 5: if (y>=z) ERROR; } return; inc(int a, int sign){ 1: if (sign){ 2: rv = a+1; } else { 3: rv = a-1; } 4: return rv;

Inline Calls in Reach Tree main(){  1: if (flag){ 2: y = inc(x,flag); 3: if (y<=x) ERROR; } else { 4: y = inc(z,flag); 5: if (y>=z) ERROR; } return; Initial 1 2 4 1,2 1,4 2,2 3,2 2,4 3,4 inc(int a, int sign){ 1: if (sign){ 2: rv = a+1; } else { 3: rv = a-1; } 4: return rv; 4,2 4,2 4,4 4,4 3 3 5 5

Inline Calls in Reach Tree Problem Repeated analysis for “inc” Exploding call contexts Initial 1 2 4 int x; //global f1(){ 1: x = 0; 2: if(*) f2(); 3: else f2(); 4: if (x<0) ERROR; return; } 1,2 1,4 f2(){ 1: if(*) f3(); 2: else f3(); return; } f3(){ 1: if(*) f4(); 2: else f4(); return; } 2,2 3,2 2,4 3,4 f4(){ 1: if(*) f5(); 2: else f5(); return; } fn(){ 1: x ++; return; } 4,2 4,2 4,4 4,4 3 3 5 5 2n nodes in Reach Tree

Inline Calls in Reach Tree Problem Repeated analysis for “inc” Exploding call contexts Cyclic call graph (Recursion) Infinite Tree! Initial 1 2 4 1,2 1,4 2,2 3,2 2,4 3,4 4,2 4,2 4,4 4,4 3 3 5 5

Solution : Procedure Summaries Summaries: Input/Output behavior Plug summaries in at each callsite … instead of inlining entire procedure [Sharir-Pnueli 81, Reps-Horwitz-Sagiv 95] Summary = set of (F  F’) F : Precondition formula describing input state F’ : Postcondition formula describing output state

Solution : Procedure Summaries Summaries: Input/Output behavior Plug summaries in at each callsite … instead of inlining entire procedure [Sharir-Pnueli 81, Reps-Horwitz-Sagiv 95, Ball-Rajamani 01] Summary = set of (F  F’) F : Precondition formula describing input state F’ : Postcondition formula describing output state inc(int a, int sign){ 1: if (sign){ 2: rv = a+1; } else { 3: rv = a-1; } 4: return rv; (: sign=0  rv > a) (sign = 0  rv < a) Q. How to compute, use summaries ?

Lazy Abstraction + Procedure Summaries Yes Safe C Program Abstract Refine No Property Trace Q. How to compute, use summaries ?

Abstraction with Summaries main(){  1: if (flag){ 2: y = inc(x,flag); 3: if (y<=x) ERROR; } else { 4: y = inc(z,flag); 5: if (y>=z) ERROR; } return; main 1 [flag!=0] 2 : flag=0 a=x sign=flag : sign=0 inc(int a, int sign){ 1: if (sign){ 2: rv = a+1; } else { 3: rv = a-1; } 4: return rv; Predicates: flag=0 , y>x , y<z sign=0 , rv>a , rv<a

Abstraction with Summaries main(){  1: if (flag){ 2: y = inc(x,flag); 3: if (y<=x) ERROR; } else { 4: y = inc(z,flag); 5: if (y>=z) ERROR; } return; main inc 1 : sign=0 1 [sign!=0] 2 : flag=0 : sign=0 2 a=x sign=flag rv=a+1 : sign=0 rv>a 4 inc(int a, int sign){ 1: if (sign){ 2: rv = a+1; } else { 3: rv = a-1; } 4: return rv; Predicates: flag=0 , y>x , y<z sign=0 , rv>a , rv<a Summary: (: sign=0  rv>a),

Summary Successor main inc Predicates: flag=0 , y>x , y<z  1: if (flag){ 2: y = inc(x,flag); 3: if (y<=x) ERROR; } else { 4: y = inc(z,flag); 5: if (y>=z) ERROR; } return; main inc 1 : sign=0 1 2 a=x sign=flag : flag=0 2 assume rv>a 3 y>x y=rv rv>a 4 inc(int a, int sign){ 1: if (sign){ 2: rv = a+1; } else { 3: rv = a-1; } 4: return rv; Predicates: flag=0 , y>x , y<z sign=0 , rv>a , rv<a Summary: (: sign=0  rv>a),

Abstraction with Summaries main(){  1: if (flag){ 2: y = inc(x,flag); 3: if (y<=x) ERROR; } else { 4: y = inc(z,flag); 5: if (y>=z) ERROR; } return; main inc 1 : sign=0 1 [flag==0] [sign=0] 2 4 : flag=0 flag=0 2 3 y>x 3 sign=0 rv>a 4 [y<=x] a=x sign=flag inc(int a, int sign){ 1: if (sign){ 2: rv = a+1; } else { 3: rv = a-1; } 4: return rv; Predicates: flag=0 , y>x , y<z sign=0 , rv>a , rv<a Summary: (: sign=0  rv>a),

Abstraction with Summaries main(){  1: if (flag){ 2: y = inc(x,flag); 3: if (y<=x) ERROR; } else { 4: y = inc(z,flag); 5: if (y>=z) ERROR; } return; main inc 1 : sign=0 1 1 sign=0 2 4 : flag=0 flag=0 2 3 2 3 y>x 3 sign=0 rv>a 4 4 rv<a a=x sign=flag inc(int a, int sign){ 1: if (sign){ 2: rv = a+1; } else { 3: rv = a-1; } 4: return rv; Predicates: flag=0 , y>x , y<z sign=0 , rv>a , rv<a Summary: (: sign=0  rv>a), (sign=0  rv<a)

Summary Successor main inc Predicates: flag=0 , y>x , y<z  1: if (flag){ 2: y = inc(x,flag); 3: if (y<=x) ERROR; } else { 4: y = inc(z,flag); 5: if (y>=z) ERROR; } return; main inc 1 : sign=0 1 1 sign=0 2 4 : flag=0 flag=0 2 3 2 3 y>x 3 3 y<z rv>a 4 4 rv<a a=x sign=flag inc(int a, int sign){ 1: if (sign){ 2: rv = a+1; } else { 3: rv = a-1; } 4: return rv; assume rv<a y=rv Predicates: flag=0 , y>x , y<z sign=0 , rv>a , rv<a Summary: (: sign=0  rv>a), (sign=0  rv<a)

Abstraction with Summaries main(){  1: if (flag){ 2: y = inc(x,flag); 3: if (y<=x) ERROR; } else { 4: y = inc(z,flag); 5: if (y>=z) ERROR; } return; main inc 1 : sign=0 1 1 sign=0 2 4 : flag=0 flag=0 2 3 2 3 y>x 3 3 y<z rv>a 4 4 rv<a [y>=z] inc(int a, int sign){ 1: if (sign){ 2: rv = a+1; } else { 3: rv = a-1; } 4: return rv; Predicates: flag=0 , y>x , y<z sign=0 , rv>a , rv<a Summary: (: sign=0  rv>a), (sign=0  rv<a)

Another Call … main inc Predicates: flag=0 ,y>x,y<z, y1>z1  1: if (flag){ 2: y = inc(x,flag); 3: if (y<=x) ERROR; } else { 4: y = inc(z,flag); 5: if (y>=z) ERROR; } 6: y1 = inc(z1,1); 7: if (y1<=z1) ERROR; return; main inc 1 : sign=0 1 1 sign=0 2 4 : flag=0 flag=0 2 3 2 3 y>x 3 3 y<z rv>a 4 4 rv<a inc(int a, int sign){ 1: if (sign){ 2: rv = a+1; } else { 3: rv = a-1; } 4: return rv; 6 6 a=z1 sign=1 : sign=0 Predicates: flag=0 ,y>x,y<z, y1>z1 sign=0 , rv>a , rv<a Summary: (: sign=0  rv>a), (sign=0  rv<a)

Another Call … Note: Predicates are well-scoped … SAFE main inc  1: if (flag){ 2: y = inc(x,flag); 3: if (y<=x) ERROR; } else { 4: y = inc(z,flag); 5: if (y>=z) ERROR; } 6: y1 = inc(z1,1); 7: if (y1<=z1) ERROR; return; main inc 1 : sign=0 1 1 sign=0 2 4 : flag=0 flag=0 2 3 2 3 y>x 3 3 y<z rv>a 4 4 rv<a Note: Predicates are well-scoped … inc(int a, int sign){ 1: if (sign){ 2: rv = a+1; } else { 3: rv = a-1; } 4: return rv; 6 6 SAFE a=z1 sign=1 y1>z1 7 assume rv>a y1=rv Predicates: flag=0 ,y>x,y<z, y1>z1 sign=0 , rv>a , rv<a Summary: (: sign=0  rv>a), (sign=0  rv<a)

Lazy Abstraction + Procedure Summaries Yes Safe C Program Abstract Refine No Property Trace Q. How to find scoped predicates ?

Traces with Procedure Calls Trace Formula pc1: x1 = 3 pc2: assume (x1>0) pc3: x3 = f1(x1) pc4: y2 = y1 pc5: y3 = f2(y2) pc6: z2 = z1+1 pc7: z3 = 2*z2 pc8: return z3 pc9: return y3 pc10: x4 = x3+1 pc11: x5 = f3(x4) pc12: assume(w1<5) pc13: return w1 pc14: assume x4>5 pc15: assume (x1=x3+2) pc1: x1 = 3 pc2: assume (x1>0) pc3: x3 = f1(x1) pc4: y2 = y1 pc5: y3 = f2(y2) pc6: z2 = z1+1 pc7: z3 = 2*z2 pc8: return z3 pc9: return y3 pc10: x4 = x3+1 pc11: x5 = f3(x4) pc12: assume(w1<5) pc13: return w1 pc14: assume x4>5 pc15: assume(x1=x3+2) Find predicate needed at point i i i

Interprocedural Analysis Trace Trace Formula NO Find predicate needed at point i YES i i NO Require at each point i: Scoped predicates YES: Variables visible at i NO: Caller’s local variables

Problems with Cutting - + i i Trace Trace Formula - i i + Caller variables common to - and + Unsuitable interpolant: not well-scoped

Scoped Cuts Trace Trace Formula Call begins i i

Scoped Cuts + - i i Predicate at pci = Interpolant from cut i Trace Trace Formula Call begins + - i i Predicate at pci = Interpolant from cut i

Common Variables + - i i Predicate at pci = Interpolant from i-cut Trace Trace Formula Common Variables Formals + - Formals i i Current locals Well-scoped Predicate at pci = Interpolant from i-cut

Example Trace m1: assume(flag!=0) m2: y=inc(x,flag) main(){  1: if (flag){ 2: y = inc(x,flag); 3: if (y<=x) ERROR; } else { 4: y = inc(z,flag); 5: if (y>=z) ERROR; } return; m1: assume(flag!=0) m2: y=inc(x,flag) i1: assume(sign!=0) i2: rv = a+1 i4: return rv m3: assume(y<=x) ERROR: inc(int a, int sign){ 1: if (sign){ 2: rv = a+1; } else { 3: rv = a-1; } 4: return rv;

Trace Formula Trace SSA Trace m1: assume(flag!=0) m2: y=inc(x,flag) i1: assume(sign!=0) i2: rv = a+1 i4: return rv m3: assume(y<=x) m1: assume(flag0!=0) m2: a0=x0, sign0=flag0 i1: assume(sign0!=0) i2: rv0=a0+1 i4: y0=rv0 m3: assume(y0 <= x0) Trace SSA Trace

Trace Formula i i Trace Trace Formula m1: assume(flag!=0) m2: y=inc(x,flag) i1: assume(sign!=0) i2: rv = a+1 i4: return rv m3: assume(y<=x) Æ flag0  0 Æ a0=x0 Æ sign0= flag0 Æ sign0  0 Æ rv0=a0+1 Æ y0=rv0 Æ y0 <= x0 Call begins i i Trace Trace Formula

Trace Formula + - i i Trace Trace Formula m1: assume(flag!=0) m2: y=inc(x,flag) i1: assume(sign!=0) i2: rv = a+1 i4: return rv m3: assume(y<=x) Æ flag0  0 Æ a0=x0 Æ sign0= flag0 Æ sign0  0 Æ rv0=a0+1 Æ y0=rv0 Æ y0 <= x0 + - i i Trace Trace Formula

Trace Formula + - i i Trace Trace Formula m1: assume(flag!=0) m2: y=inc(x,flag) i1: assume(sign!=0) i2: rv = a+1 i4: return rv m3: assume(y<=x) Æ flag0  0 Æ a0=x0 Æ sign0= flag0 Æ sign0  0 Æ rv0=a0+1 Æ y0=rv0 Æ y0 <= x0 a0 Interpolate + - rv0 a0 i i rv0 rv0> a0 Trace Trace Formula

Lazy Abstraction + Procedure Summaries Yes Safe C Program Abstract Refine No Property Trace Q. How to find scoped predicates ? Solution: Scoped Cuts + Interpolation

Review : Procedures Modular Analysis via Summaries Summary = (In,Out) vertices’ formulas Requires scoped predicates Scoped cuts + Interpolation

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 [CQUAL, ESP, MC] Scalable

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 Lazy Abstraction - loop invariants + Behaviors encoded in logic Refine + Theorem provers Computing Successors,Refine Program Analysis - Imprecise + Abstraction Shrink state space Lazy Abstraction Model Checking - Finite-state model, state explosion + State Space Exploration Path Sensitive Analysis + Counterexamples Finding Relevant Facts

Lazy Abstraction: Main Ideas Predicates: Abstract infinite program states Counterexample-guided Refinement: Find predicates tailored to prog, property Abstraction : Expensive Reachability Tree Refinement : Find predicates, use locations Proof of unsat of TF + Interpolation

Thank you