Ranjit Jhala Rupak Majumdar Interprocedural Analysis of Asynchronous Programs.

Slides:



Advertisements
Similar presentations
Dataflow Analysis for Datarace-Free Programs (ESOP 11) Arnab De Joint work with Deepak DSouza and Rupesh Nasre Indian Institute of Science, Bangalore.
Advertisements

Bounded Model Checking of Concurrent Data Types on Relaxed Memory Models: A Case Study Sebastian Burckhardt Rajeev Alur Milo M. K. Martin Department of.
Automated Theorem Proving Lecture 1. Program verification is undecidable! Given program P and specification S, does P satisfy S?
An Abstract Interpretation Framework for Refactoring P. Cousot, NYU, ENS, CNRS, INRIA R. Cousot, ENS, CNRS, INRIA F. Logozzo, M. Barnett, Microsoft Research.
Data-Flow Analysis II CS 671 March 13, CS 671 – Spring Data-Flow Analysis Gather conservative, approximate information about what a program.
Greta YorshEran YahavMartin Vechev IBM Research. { ……………… …… …………………. ……………………. ………………………… } T1() Challenge: Correct and Efficient Synchronization { ……………………………
Context-Sensitive Interprocedural Points-to Analysis in the Presence of Function Pointers Presentation by Patrick Kaleem Justin.
Abstraction and Modular Reasoning for the Verification of Software Corina Pasareanu NASA Ames Research Center.
Data-Flow Analysis Framework Domain – What kind of solution is the analysis looking for? Ex. Variables have not yet been defined – Algorithm assigns a.
What’s Decidable for Asynchronous Programs? Rupak Majumdar Max Planck Institute for Software Systems Joint work with Pierre Ganty, Michael Emmi, Fernando.
1 Symbolic Execution for Model Checking and Testing Corina Păsăreanu (Kestrel) Joint work with Sarfraz Khurshid (MIT) and Willem Visser (RIACS)
© Anvesh Komuravelli Spacer Automatic Abstraction in SMT-Based Unbounded Software Model Checking Anvesh Komuravelli Carnegie Mellon University Joint work.
Timed Automata.
Rigorous Software Development CSCI-GA Instructor: Thomas Wies Spring 2012 Lecture 13.
PARTIAL-COHERENCE ABSTRACTIONS FOR RELAXED MEMORY MODELS Presented by Michael Kuperstein, Technion Joint work with Martin Vechev, IBM Research and Eran.
Proofs from Tests Nels E. Beckman Aditya V. Nori Sriram K. Rajamani Robert J. Simmons Carnegie Mellon UniversityMicrosoft Research India Carnegie Mellon.
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.
Permissive Interfaces Tom Henzinger Ranjit Jhala Rupak Majumdar.
Static Analysis of Embedded C Code John Regehr University of Utah Joint work with Nathan Cooprider.
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.
Abstractions. Outline Informal intuition Why do we need abstraction? What is an abstraction and what is not an abstraction A framework for abstractions.
Thread-modular Abstraction Refinement Tom Henzinger Ranjit Jhala Rupak Majumdar [UC Berkeley] Shaz Qadeer [Microsoft Research]
Next Section: Pointer Analysis Outline: –What is pointer analysis –Intraprocedural pointer analysis –Interprocedural pointer analysis (Wilson & Lam) –Unification.
Program analysis Mooly Sagiv html://
Synergy: A New Algorithm for Property Checking
Counter Example Guided Refinement CEGAR Mooly Sagiv.
Race Checking by Context Inference Tom Henzinger Ranjit Jhala Rupak Majumdar UC Berkeley.
Range Analysis. Intraprocedural Points-to Analysis Want to compute may-points-to information Lattice:
Formal Verification Group © Copyright IBM Corporation 2008 IBM Haifa Labs SAT-based unbounded model checking using interpolation Based on a paper “Interpolation.
Temporal-Safety Proofs for Systems Code Thomas A. Henzinger Ranjit Jhala Rupak Majumdar George Necula Westley Weimer Grégoire Sutre UC Berkeley.
Overview of program analysis Mooly Sagiv html://
Computing Over­Approximations with Bounded Model Checking Daniel Kroening ETH Zürich.
Comparison Caller precisionCallee precisionCode bloat Inlining context-insensitive interproc Context sensitive interproc Specialization.
Ranjit Jhala Rupak Majumdar Interprocedural Analysis of Asynchronous Programs.
Model Checking Lecture 5. Outline 1 Specifications: logic vs. automata, linear vs. branching, safety vs. liveness 2 Graph algorithms for model checking.
Formal Verification of SpecC Programs using Predicate Abstraction Himanshu Jain Daniel Kroening Edmund Clarke Carnegie Mellon University.
Lazy Abstraction Lecture 3 : Partial Analysis Ranjit Jhala UC San Diego With: Tom Henzinger, Rupak Majumdar, Ken McMillan, Gregoire Sutre.
Pointer analysis. Pointer Analysis Outline: –What is pointer analysis –Intraprocedural pointer analysis –Interprocedural pointer analysis Andersen and.
Verifying Concurrent Message- Passing C Programs with Recursive Calls Sagar Chaki, Edmund Clarke, Nicholas Kidd, Thomas Reps, and Tayssir Touili.
PRESTO Research Group, Ohio State University Interprocedural Dataflow Analysis in the Presence of Large Libraries Atanas (Nasko) Rountev Scott Kagan Ohio.
Inferring Specifications to Detect Errors in Code Mana Taghdiri Presented by: Robert Seater MIT Computer Science & AI Lab.
Race Checking by Context Inference Tom Henzinger Ranjit Jhala Rupak Majumdar UC Berkeley.
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.
A Framework on Synchronization Verification in System-Level Design Thanyapat Sakunkonchak Satoshi Komatsu Masahiro Fujita Fujita Laboratory University.
Convergence of Model Checking & Program Analysis Philippe Giabbanelli CMPT 894 – Spring 2008.
Symbolic Execution with Abstract Subsumption Checking Saswat Anand College of Computing, Georgia Institute of Technology Corina Păsăreanu QSS, NASA Ames.
Dataflow Analysis for Concurrent Programs using Datarace Detection Ravi Chugh, Jan W. Voung, Ranjit Jhala, Sorin Lerner LBA Reading Group Michelle Goodstein.
1 Turing’s Thesis. 2 Turing’s thesis: Any computation carried out by mechanical means can be performed by a Turing Machine (1930)
Generating Precise and Concise Procedure Summaries Greta Yorsh Eran Yahav Satish Chandra.
© Copyright 2008 STI INNSBRUCK Intelligent Systems Propositional Logic.
1 MSR/Cambridge Formal Verification Overview Byron Cook Microsoft Research, Cambridge.
Pointer Analysis – Part I CS Pointer Analysis Answers which pointers can point to which memory locations at run-time Central to many program optimization.
CS357 Lecture 13: Symbolic model checking without BDDs Alex Aiken David Dill 1.
Verifying Component Substitutability Nishant Sinha Sagar Chaki Edmund Clarke Natasha Sharygina Carnegie Mellon University.
DFA foundations Simone Campanoni
Pointer Analysis Lecture 2
Simone Campanoni DFA foundations Simone Campanoni
Over-Approximating Boolean Programs with Unbounded Thread Creation
CSE 311: Foundations of Computing
Abstractions from Proofs
Abstraction, Verification & Refinement
Predicate Abstraction
BLAST: A Software Verification Tool for C programs
Presentation transcript:

Ranjit Jhala Rupak Majumdar Interprocedural Analysis of Asynchronous Programs

client(rc) Asynchronous Programs reqs(){ if(r == NULL){ async reqs(); return; } rc = malloc(…); if (rc == NULL){ return NO_MEM; } async client(rc,r->id); r = r->next; reqs(); } client(*c,id){... c->id = id;... return; } main(){... async reqs();... } global request_list *r; v0v0 v1v1 v2v2 v3v3 v4v4 v5v5 v6v6 v 10 v7v7 v8v8 v9v9 v 11 v 12 v 13 v 14 v 15 reqs main reqs client [r!=0] c->id=id rc=malloc() r=r->next [r==0] [rc!=0][rc==0] reqs

Asynchronous Programs reqs(){ if(r == NULL){ async reqs(); return; } rc = malloc(…); if (rc == NULL){ return NO_MEM; } async client(rc,r->id); r = r->next; reqs(); } client(*c,id){... c->id = id;... return; } main(){... async reqs();... } global request_list *r; v0v0 v1v1 v2v2 v3v3 v4v4 v5v5 v6v6 v 10 v7v7 v8v8 v9v9 v 11 v 12 v 13 v 14 v 15 reqs main reqs client [r!=0] c->id=id rc=malloc() r=r->next [r==0] [rc!=0][rc==0] reqs client(rc)

Asynchronous Programs Dispatch Location V 3 Calls all other functions client reqs v0v0 v1v1 v2v2 v3v3 v5v5 v6v6 v7v7 v8v8 v9v9 v 11 v 13 v 14 v 15 reqs main reqs client reqs v4v4 v 10 v 12

Asynchronous Program Execution client reqs v0v0 v1v1 v2v2 v3v3 v4v4 v5v5 v6v6 v 10 v7v7 v8v8 v9v9 v 11 v 12 v 13 v 14 v 15 reqs main reqs client [r!=0] c->id=id rc=malloc() r=r->next [r==0] [rc!=0][rc==0] reqs PC client(rc)

Asynchronous Program Execution Pending Calls reqs client reqs v0v0 v1v1 v2v2 v3v3 v4v4 v5v5 v6v6 v 10 v7v7 v8v8 v9v9 v 11 v 12 v 13 v 14 v 15 reqs main reqs client [r!=0] c->id=id rc=malloc() r=r->next [r==0] [rc!=0][rc==0] reqs PC Async calls stored in set client(rc)

Asynchronous Program Execution Pending Calls reqs client reqs v0v0 v1v1 v2v2 v3v3 v4v4 v5v5 v6v6 v 10 v7v7 v8v8 v9v9 v 11 v 12 v 13 v 14 v 15 reqs main reqs client [r!=0] c->id=id rc=malloc() r=r->next [r==0] [rc!=0][rc==0] reqs Async calls stored in set –Execute at dispatch loop PC client(rc)

Asynchronous Program Execution Pending Calls client reqs v0v0 v1v1 v2v2 v3v3 v4v4 v5v5 v6v6 v 10 v7v7 v8v8 v9v9 v 11 v 12 v 13 v 14 v 15 reqs main reqs client [r!=0] client(rc) c->id=id rc=malloc() r=r->next [r==0] [rc!=0][rc==0] reqs Async calls stored in set –Execute at dispatch loop PC

Asynchronous Program Execution Pending Calls client(…) client reqs v0v0 v1v1 v2v2 v3v3 v4v4 v5v5 v6v6 v 10 v7v7 v8v8 v9v9 v 11 v 12 v 13 v 14 v 15 reqs main reqs client [r!=0] c->id=id rc=malloc() r=r->next [r==0] [rc!=0][rc==0] reqs Async calls stored in set –Execute at dispatch loop Sync calls exec at call site PC client(rc)

Asynchronous Program Execution Pending Calls client(…) client reqs v0v0 v1v1 v2v2 v3v3 v4v4 v5v5 v6v6 v 10 v7v7 v8v8 v9v9 v 11 v 12 v 13 v 14 v 15 reqs main reqs client [r!=0] c->id=id rc=malloc() r=r->next [r==0] [rc!=0][rc==0] reqs PC Async calls stored in set –Execute at dispatch loop Sync calls exec at call site client(rc)

Asynchronous Program Execution Pending Calls client(…) reqs client reqs v0v0 v1v1 v2v2 v3v3 v4v4 v5v5 v6v6 v 10 v7v7 v8v8 v9v9 v 11 v 12 v 13 v 14 v 15 reqs main reqs client [r!=0] c->id=id rc=malloc() r=r->next [r==0] [rc!=0][rc==0] reqs PC Async calls stored in set –Execute at dispatch loop Sync calls exec at call site client(rc)

Asynchronous Program Execution Pending Calls client(…) reqs client reqs v0v0 v1v1 v2v2 v3v3 v4v4 v5v5 v6v6 v 10 v7v7 v8v8 v9v9 v 11 v 12 v 13 v 14 v 15 reqs main reqs client [r!=0] c->id=id rc=malloc() r=r->next [r==0] [rc!=0][rc==0] reqs PC Async calls stored in set –Execute at dispatch loop –Order is non-deterministic Sync calls exec at call site PC client(rc)

Asynchronous Programs Why? Latency hiding and Parallelism Domains: Distributed Systems Web Servers Event/Interrupt driven Embedded Systems Discrete-event Simulation Languages and Libraries: Java + Atomic Methods LibAsync, LibEvent, LibEel NesC

client(rc) Q: How to Analyze Async Programs ? v0v0 v1v1 v2v2 v3v3 v4v4 v5v5 v6v6 v 10 v7v7 v8v8 v9v9 v 11 v 12 v 13 v 14 v 15 reqs main reqs client [r!=0] c->id=id rc=malloc() r=r->next [r==0] [rc!=0][rc==0] client reqs Prove dereference of c is safe i.e. c not null at v 13 r rc c (Must) Non-null (May) Null r rc c r c Dataflow Facts

client(rc) Verification via Dataflow Analysis v0v0 v1v1 v2v2 v3v3 v4v4 v5v5 v6v6 v 10 v7v7 v8v8 v9v9 v 11 v 12 v 13 v 14 v 15 reqs main reqs client [r!=0] c->id=id rc=malloc() r=r->next [r==0] [rc!=0][rc==0] client reqs Prove Flow fact holds at v 13 r rc c (Must) Non-null (May) Null r rc c r c Dataflow Facts c

client(rc) Dataflow Analysis v0v0 v1v1 v2v2 v3v3 v4v4 v5v5 v6v6 v 10 v7v7 v8v8 v9v9 v 11 v 12 v 13 v 14 v 15 reqs main reqs client [r!=0] c->id=id rc=malloc() r=r->next [r==0] [rc!=0][rc==0] client reqs 1 st Attempt Treat asynchronous calls as synchronous r r rc r r r r rc rc Prove Flow fact holds at v 13 c Proof “works” … but unsoundly deduces global r is non-null!

client(rc) Dataflow Analysis v0v0 v1v1 v2v2 v3v3 v4v4 v5v5 v6v6 v 10 v7v7 v8v8 v9v9 v 11 v 12 v 13 v 14 v 15 reqs main reqs client [r!=0] c->id=id rc=malloc() r=r->next [r==0] [rc!=0][rc==0] client reqs 1 st Attempt Treat asynchronous calls as synchronous Unsound Global r may change between call, dispatch Idea Separately track local and global facts rc

client(rc) Dataflow Analysis v0v0 v1v1 v2v2 v3v3 v4v4 v5v5 v6v6 v 10 v7v7 v8v8 v9v9 v 11 v 12 v 13 v 14 v 15 reqs main reqs client [r!=0] c->id=id rc=malloc() r=r->next [r==0] [rc!=0][rc==0] client reqs 2 nd Attempt Only execute async calls from dispatch location

client(rc) Dataflow Analysis v0v0 v1v1 v2v2 v3v3 v4v4 v5v5 v6v6 v 10 v7v7 v8v8 v9v9 v 11 v 12 v 13 v 14 v 15 reqs main reqs client [r!=0] c->id=id rc=malloc() r=r->next [r==0] [rc!=0][rc==0] client reqs 2 nd Attempt Only execute async calls from dispatcher Imprecise Initial value of formals ? All values ( > ) too coarse Idea Track pending calls with formals at call-site

Encoding Pending Calls as Flow Facts Idea Track pending calls and formals at call-site Idea: Counters - For each kind of async call £ input fact: Count number of pending calls of kind - Expanded DFA facts: Dataflow facts £ Counters reqs 1 client, 5 client, 0 c c

client(rc) Dataflow Analysis v0v0 v1v1 v2v2 v3v3 v4v4 v5v5 v6v6 v 10 v7v7 v8v8 v9v9 v 11 v 12 v 13 v 14 v 15 reqs main reqs client [r!=0] c->id=id rc=malloc() r=r->next [r==0] [rc!=0][rc==0] client reqs 3 rd Attempt Count # pending calls of each kind reqs 1 client, 5 client, 0 c c

client(rc) Dataflow Analysis v0v0 v1v1 v2v2 v3v3 v4v4 v5v5 v6v6 v 10 v7v7 v8v8 v9v9 v 11 v 12 v 13 v 14 v 15 reqs main reqs client [r!=0] c->id=id rc=malloc() r=r->next [r==0] [rc!=0][rc==0] client reqs Non-Terminating #Pending calls unbounded due to recursion, loops Idea Overapproximate via Abstract counters 3 rd Attempt Count # pending calls of each kind

Dealing with Unbounded Async Calls Over-Approximations : k 1 -Abstract Counters - For each async call £ input fact: Abstractly count number of pending calls of each kind - Values > k, abstracted to infinity 1 - Finite counter values = {0,1,…,k, 1 } - Finite DFA facts: Dataflow facts £ k 1 -Abs counters - Dataflow Analysis Terminates reqs 1 client, 5 client, 0 c c 1

reqs 1 Example: (k=1) 1 Abstraction reqs 0 client, 0 c c PC

reqs 1 2 reqs 1 client, 0 c c PC Example: (k=1) 1 Abstraction

reqs client reqs reqs 0 client, 0 c c PC Example: (k=1) 1 Abstraction

reqs client reqs reqs 0 client, 1 client, 0 c c PC Example: (k=1) 1 Abstraction

reqs client reqs client reqs 0 client, 1 client, 0 c c PC Example: (k=1) 1 Abstraction

reqs client reqs client reqs reqs 0 client, 1 client, 0 c c PC Example: (k=1) 1 Abstraction

reqs client reqs client reqs reqs 0 client, 1 client, 0 c c PC Example: (k=1) 1 Abstraction

reqs client reqs client reqs client reqs reqs 1 client, 1 client, 0 c c PC Example: (k=1) 1 Abstraction

reqs client reqs client reqs client reqs client reqs 1 client, 1 client, 0 c c PC Example: (k=1) 1 Abstraction

reqs client reqs client reqs client reqs client reqs 1 client, 1 client, 0 c c PC Example: (k=1) 1 Abstraction Valid

reqs client reqs client reqs client reqs client reqs 1 client, 1 client, 0 c c PC Valid Invalid Example: (k=1) 1 Abstraction No matching async call Over-Approx: k 1 -Abstraction - Considers all valid paths - Plus, some invalid paths - DFA on superset of valid paths

Over-approximate/Sound - Works for example … but imprecise in general - How to do exact DFA over set of valid paths ? Dealing with Unbounded Async Calls Over-Approx: k 1 -Abstraction - Considers all valid paths - Plus, some invalid paths - DFA on superset of valid paths Idea How bad is over-approximation ? Find out using under-approximation!

Computing Under-Approximate Solutions Under-Approximations: k-Abstract Counters - For each async call £ input fact: Abstractly count number of pending calls of each kind - Values > k, abstracted to k - Effect: All calls after k are “dropped” - Finite counter values = {0,1,…,k} - Finite dataflow facts £ k-Abs counters, ) termination reqs 1 client, 5 client, 0 c c 1

reqs client reqs client reqs 0 client, 1 client, 0 c c PC Example: (k=1) Abstraction Already (k=1) pending calls with given input fact

reqs client reqs client Example: (k=1) Abstraction Already (k=1) pending calls with given input fact Effect: call at step 5 is “dropped” Only one pending call ! reqs 0 client, 1 client, 0 c c PC

reqs client reqs client reqs client reqs Example: (k=1) Abstraction reqs 1 client, 1 client, 0 c c PC Effect: call at step 5 is “dropped” Only one pending call !

Effect: call at step 5 is “dropped” Only one pending call ! reqs client reqs client reqs client reqs client reqs 1 client, 0 c c PC Example: (k=1) Abstraction There is a matching async call But no more calls in (k=1)-abstract pending set !

reqs client reqs client reqs client reqs client PC Example: (k=1) Abstraction Valid but ignored by k-abstraction ? But no more calls in (k=1)-abstract pending set !

reqs client reqs client reqs client reqs client Example: (k=1) Abstraction Valid but ignored by k-abstraction Under-Approx: k-Abstraction - Ignores all invalid paths - plus, some valid paths - DFA on subset of valid paths - Under-Approx. DFA solution

What we have: For all K … Require Exact DFA on Valid Paths K 1 -Abstract DFA Over-Approx Paths K-Abstract DFA Under-Approx Paths Both computable via Standard DFA [RHS95]

Increase K to Increase Precision Require Exact DFA on Valid Paths K-Abstract DFA Under-Approx Paths K 1 -Abstract DFA Over-Approx Paths K++ How do we compute exact DFA Solution ?

Theorem: There exists K … Require Exact DFA on Valid Paths K 1 -Abstract DFA Over-Approx Paths K-Abstract DFA Under-Approx Paths Approximations Converge! To Exact DFA on Valid Paths K 1 -Abstract DFA Over-Approx K-Abstract DFA Under-Approx

Algorithm Require Exact DFA on Valid Paths AsyncDFA(){ k := 0 repeat over := DFA(k 1 -Counter); under := DFA(k-Counter); until (over = under); return over; } Interprocedural Analysis via Summaries [Sharir-Pnueli 80, Reps-Horwitz-Sagiv 95]

Proof “Isn’t it obvious ? Only finitely many solutions, after all …” Yes, but over- and under- approximations may converge to different fix points…

Proof Sketch (Buzzwords) Counters are Well Quasi Ordered Pre * exists –Initial configurations reaching a location –Constructable via complex backward algorithm –[Esparza-Finkel-Mayr 98] –[Sen-Vishwanathan 06] Magic k exists due to existence of Pre * –Simple forward algorithm –[PLDI 04, Raskin-Schnoebelen 04]

Application: Safety Verification Ground Dataflow Facts = Predicate Abstraction Implemented on BLAST framework - Lazy Interprocedural DFA [POPL 02] –Predicates automatically found via Counterexample Formula Interpolation [POPL 04] –Reduced Product of Predicate Abstraction, Counter lattice [FSE 05]

Preliminary Experiments C LibEvent Programs –Load Balancer –Network Simulator Properties –Buffer Overflow –Null Pointer Dereference –Protocol State Several proved, bugs found

Conclusions Boost your pet Analysis to work on Async Programs For async calls (events) exact solution computable –Unlike threads [Ramalingam 00] Optimizations directly carry over: –Procedure summarization, –On-the-fly exploration, –Demand-driven, … Proof messy but algorithm very simple EXPSPACE-Hard –but early experiments cause for optimism –magic k = 1

Merci ?