Download presentation
Presentation is loading. Please wait.
Published byPhilip Fields Modified over 9 years ago
1
Ranjit Jhala Rupak Majumdar Interprocedural Analysis of Asynchronous Programs
2
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
3
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)
4
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
5
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)
6
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)
7
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)
8
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
9
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)
10
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)
11
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)
12
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)
13
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
14
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
15
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
16
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!
17
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
18
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
19
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
20
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
21
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
22
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
23
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
24
reqs 1 Example: (k=1) 1 Abstraction reqs 0 client, 0 c c PC
25
reqs 1 2 reqs 1 client, 0 c c PC Example: (k=1) 1 Abstraction
26
reqs client reqs 1 2 3 reqs 0 client, 0 c c PC Example: (k=1) 1 Abstraction
27
reqs client reqs 1 2 3 4 reqs 0 client, 1 client, 0 c c PC Example: (k=1) 1 Abstraction
28
reqs client reqs client 1 2 3 5 4 reqs 0 client, 1 client, 0 c c PC Example: (k=1) 1 Abstraction
29
reqs client reqs client reqs 1 2 3 6 5 4 reqs 0 client, 1 client, 0 c c PC Example: (k=1) 1 Abstraction
30
reqs client reqs client reqs 1 2 3 7 6 5 4 reqs 0 client, 1 client, 0 c c PC Example: (k=1) 1 Abstraction
31
reqs client reqs client reqs client reqs 1 2 3 8 7 6 5 4 reqs 1 client, 1 client, 0 c c PC Example: (k=1) 1 Abstraction
32
reqs client reqs client reqs client reqs client 1 2 3 8 7 6 5 4 reqs 1 client, 1 client, 0 c c PC Example: (k=1) 1 Abstraction
33
reqs client reqs client reqs client reqs client 1 2 3 9 8 7 6 5 4 10 reqs 1 client, 1 client, 0 c c PC Example: (k=1) 1 Abstraction Valid
34
reqs client reqs client reqs client reqs client 1 2 3 9 8 7 6 5 4 10 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
35
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!
36
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
37
reqs client reqs client 1 2 3 5 4 reqs 0 client, 1 client, 0 c c PC Example: (k=1) Abstraction Already (k=1) pending calls with given input fact
38
reqs client reqs client 1 2 3 5 4 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
39
reqs client reqs client reqs client reqs 1 2 3 8 7 6 5 4 Example: (k=1) Abstraction reqs 1 client, 1 client, 0 c c PC Effect: call at step 5 is “dropped” Only one pending call !
40
Effect: call at step 5 is “dropped” Only one pending call ! reqs client reqs client reqs client reqs client 1 2 3 8 7 6 5 4 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 !
41
reqs client reqs client reqs client reqs client 1 2 3 9 8 7 6 5 4 PC Example: (k=1) Abstraction Valid but ignored by k-abstraction ? But no more calls in (k=1)-abstract pending set !
42
reqs client reqs client reqs client reqs client 1 2 3 9 8 7 6 5 4 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
43
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]
44
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 ?
45
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
46
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]
47
Proof “Isn’t it obvious ? Only finitely many solutions, after all …” Yes, but over- and under- approximations may converge to different fix points…
48
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]
49
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]
50
Preliminary Experiments C LibEvent Programs –Load Balancer –Network Simulator Properties –Buffer Overflow –Null Pointer Dereference –Protocol State Several proved, bugs found
51
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
52
Merci ?
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.