Download presentation
Presentation is loading. Please wait.
Published byKevin Collin Webster Modified over 8 years ago
1
Partially Disjunctive Shape Analysis Roman Manevich Mooly Sagiv Ganesan Ramalingam advisor: consultant:
2
2 Non-blocking stack [Treiber, 1986] [1] void push(Stack *S, data_type v) { [2] Node *x = alloc(sizeof(Node)); [3] x->d = v; [4] do { [5] Node *t = S->Top; [6] x->n = t; [7] } while (!CAS(&S->Top,t,x)); [8] } [9] data_type pop(Stack *S){ [10] do { [11] Node *t = S->Top; [12] if (t == NULL) [13] return EMPTY; [14] Node *s = t->n; [15] data_type r = t->d; [16] } while (!CAS(&S->Top,t,s)); [17] return r; [18] } lock-free: benign data races unbounded dynamic memory unbounded number of threads x points to valid memory? can cause memory leak? does list remain acyclic? stack linearizable? Automatic proof of linearizability for an unbounded number of threads
3
3 x y 1 >1 Shape graph bounded abstraction x y Concrete heap Canonical heap abstraction [Sagiv et al., TOPLAS 02] Abstraction for (possibly cyclic) lists [M. et al., VMCAI 05] Abstracts length of “list segments” Retains shape of heap Shape abstractions
4
4 x y 1 >1 Abstraction and concretization x y x y x y...
5
5 Abstraction and concretization a b a’ a’ overapproximates a a’ represents b Concrete domain (partial order ) Abstract domain (partial order )
6
6 x y >1 Sound abstract transformers t=x->n x y 1 1 t x y 1 >1 t
7
7 Most precise transformer [Cousot & Cousot POPL 77] st Concrete domainAbstract domain
8
8 Sound abstract transformer st Concrete domainAbstract domain
9
9 x y >1 Sound abstract transformers t=x->n x y 1 1 t x y 1 >1 t x y t
10
Inferring safe invariants 10 [1] Node * create(int size){ [2] Node * x = NULL; [3] while (size-- > 0) { [4] Node * t = (Node *) malloc(sizeof(Node)); [5] t->n = x; [6] x = t; } [7] return x; } null x t [3] null x t [5] null x t [5] 1 null x [5] t >1 [6] null x t 1>1 null x 1 t [6] 1 null x t [6] 1 null x t [4] 1 [7] [3] null x t [7] >1 [4] [3] null x t [7] >1 [4] [3] [4] [7]
11
11 Disjunctive school DNF-like invariants 1 (v) … n (v) Join is disjunction Model checking Partially disjunctive school CNF-like invariants 1 (v) … n (v) v : (v) Loss of information in join Abstract Interpretation Dataflow
12
12 Research problem Problem Disjunctive shape abstractions Join is disjunction “Too” precise Yields exponential blow-ups My solution Partially disjunctive shape abstractions Modular aspects Precise enough Reduce exponential factors Orders of magnitude speed-ups 12
13
13 Main challenge Can we develop useful partially disjunctive abstractions for the heap? Challenging setting: objects & threads are Anonymous Unbounded 13
14
14 Main thesis results Framework for partially disjunctive heap abstractions based on heap decomposition Correlations within subheap maintained Disjunctive maintains correlations in full heap Correlations with other parts of heap abstracted away Smaller subheaps lead to reduced state space Reuse subheaps System for automatically generating abstract interpreters based on user-specified heap decomposition [SAS 08] Guaranteed soundness Feasible transformers Applications Sequential programs manipulating multiple data structures [TACAS 07] First automatic proof of linearizability for fine-grained concurrent programs with an unbounded number of threads [CAV 08]
15
15 Outline Disjunctive vs. partially disjunctive abstractions Partially disjunctive abstraction via heap decomposition “Thread-modular” analysis for fine-grained concurrency
16
16 Abstraction by partitioning concrete state space
17
17 Abstraction by partitioning abstract state space Abstract state: (4 x 5 2 y 3) (2 x 3 4 y 5) (5 x 6 4 y 5) (3 x 4 5 y 6) (7 x 8 4 y 5) (5 x 6 7 y 8) (7 x 8 6 y 7)
18
18 Disjunctive abstraction (4 x 5 2 y 3) (2 x 3 4 y 5) (5 x 6 4 y 5) (3 x 4 5 y 6) (7 x 8 4 y 5) (5 x 6 7 y 8) (7 x 8 6 y 7)
19
19 Disjunctive abstraction (4 x 5 2 y 3) (2 x 3 4 y 5) (5 x 6 4 y 5) (3 x 4 5 y 6) (7 x 8 4 y 5) (5 x 6 7 y 8) (7 x 8 6 y 7)
20
20 Partially disjunctive abstraction 2 x 6 2 y 6 5 x 8 4 y 8
21
21 Partially disjunctive abstraction Join coarser than disjunction 2 x 8 2 y 8
22
22 No information loss from merging control flow paths Exponential space blowups Inferring abstractions CEGAR is well-studied Loses many correlations Drastically reduces state space What are the important correlations? Learning from multiple traces Disjunctive abstractions Partially disjunctive abstractions
23
23 Partially disjunctive abstraction and the heap Scaling is major issue Infinite state space Existing abstractions are doubly-exponential Concurrency drastically increases analysis cost Cartesian abstraction for heap non-trivial Storeless semantics Address of objects and threads coincidental Unbounded memory and number of threads Which parts of the heap need to be correlated? CEGAR-like techniques may help The cost of analysis may sometimes increase when more correlations are ignored
24
24 Heap Decomposition idea z xy p q z xy p q
25
25 Heap Decomposition idea xyz p q xyz p q
26
26 Heap Decomposition idea z xyxyz p q p q z xy p qxyz p q z xy p qxyzp q z xy p q
27
27 Connected Components Decomposition
28
28 t … x n = y y n = z assert x n n z Disjunctive shape analysis xyz xyz xyz xyzxyz
29
29 t … x n = y y n = z assert x n n z xyz xyz xyz xyz Independent attribute (Cartesian) shape analysis [Sagiv et al., TOPLAS 98]
30
30 Space of heap abstractions Disjunctive shape abstractions Canonical heap abstraction [Sagiv et al., TOPLAS 02] (cyclic) list abstraction [M. et al., VMCAI 05] Independent attribute shape analysis [Sagiv et al., TOPLAS 98] Connected component decomposition [M. et al., TACAS 07] more precise
31
31 Abstraction splits heap into set of (disjoint) connected components Special case of heap decomposition What is maintained All aliasing relations All reachability relations What is lost Correlations between data structures xyz Connected components decomposition
32
32 Connected components decomposition zxy Abstraction splits heap into set of (disjoint) connected components Special case of heap decomposition What is maintained All aliasing relations All reachability relations What is lost Correlations between data structures xyz decompose
33
33 x yz ? ? y xz ? ? z xy ? ? What a connected component denotes ConnComp({x, y, z}) noedges() ConnComp({ x,y, z}) noedges() ConnComp({ x, y,z} ) noedges()
34
34 What a set of components denotes zxy xyz ConnComp({x, y, z}) edges{(x,y)} ConnComp({ x, y,z}) noedges() ConnComp({x, y, z}) noedges() ConnComp({ x, y,z}) edges{(y,z)}
35
35 What a set of components denotes zxy xyz xyzxyz Meaning of a set of subheaps: full heaps composed from subheaps
36
36 What a set of components denotes zxy xyz xyzxyz Meaning of a set of subheaps: full heaps composed from subheaps Full heap contains all variables z x z x ConnComp({ x, y,z}) ConnComp({x, y, z}) noedges()
37
37 What a set of components denotes zxy xyz xyzxyz Meaning of a set of subheaps: full heaps composed from subheaps Full heap contains all variables Subheaps with common variables inconsistent xy ConnComp({x, y, z}) edges{(x,y)} ConnComp({ x, y,z}) edges{(y,z)} yz ConnComp({x, y, z}) ConnComp({ x, y,z}) edges{(x,y), (y,z)}
38
38 Shape example revisited … x.n = y y.n = z assert x n n z zxy xyz zxy xyz zxy xyz xyz
39
39 h1t1... h2t2... h1t1h2t2 // @assume h1!=NULL && h1==t1 && h1 n==NULL && // h2!=NULL && h2==t2 && h2 n==NULL // // @loop_invariant Reach(h1,t1) && // Reach(h2,t2) && // DisjointLists(h1,h2) EnqueueEvents() { L1: while (...) { List temp = new List(getEvent()); if (nondet()) { t1 n = temp; t1 = temp; } else { t2 n = temp; t2 = temp; } } } Correlations between properties of two lists irrelevant for proving loop invariant Idea: track properties of each list independently Example: multiple data structures
40
40 size>2 size=2size=1 size>2 size=2size=1 Full abstract heaps at loop head h1 >1 t1 h2t2 1 h2t2 h1t1 >1 h2t2 1 h1t1 >1 h2t2 >1 h1t1 1 h2t2 1 h1t1 1 h2t2 >1 h1t1 1 h2t2 h1t1 >1 h2t2 h1t1 h1t1 h2t2
41
41 Common subgraphs h1 >1 t1 h2t2 1 h2t2 h1t1 >1 h2t2 1 h1t1 >1 h2t2 >1 h1t1 1 h2t2 1 h1t1 1 h2t2 >1 h1t1 1 h2t2 h1t1 >1 h2t2 h1t1 h1t1 h2t2
42
42 Common subgraphs h1 >1 t1 h2t2 1 h2t2 h1t1 >1 h2t2 1 h1t1 >1 h2t2 >1 h1t1 1 h2t2 1 h1t1 1 h2t2 >1 h1t1 1 h2t2 h1t1 >1 h2t2 h1t1 h1t1 h2t2
43
43 State space reduction h1t1 h1 1 t1 h1 >1 t1 h2t2 h2 1 t2 h2 >1 t2 For k lists: full heap abstraction generates 3 k abstract states decomposed heap abstraction generates 3×k abstract states Connected components abstraction precise enough to prove invariant reusing subgraphs reduces exponential blow-ups
44
44 Transformers for connected components decomposition Most precise transformer NP-complete Developed efficient transformers Polynomial Compose at most 2-3 subgraphs Useful Applied to windows device drivers x200 speedup
45
45 // @assume h1!=NULL && h1==t1 && h1 n==NULL && // h2!=NULL && h2==t2 && h2 n==NULL // // @loop_invariant Reach(h1,t1) && // Reach(h2,t2) && // DisjointLists(h1,h2) EnqueueEvents() { L1: while (...) { List temp = new List(getEvent()); if (nondet()) { t1 n = temp; t1 = temp; } else { t2 n = temp; t1 = temp; // should be t2 = tmp; } } } Example with bug
46
46 Abstract error trace h1t1h2t2 List temp = new List(getEvent()); h1t1h2t2temp t2 n = temp; h1t1h2t2temp t1 = temp; h1t1h2t2temp Reach(h1,t1)
47
47 State space reduction (89,430 / 7,733) number of shape graphs number of subgraphs x
48
48 Time speedup full shape graph analysis time graph decomposition analysis time x (552.6 / 2.6)
49
49 Beyond connected component decomposition Realistic programs contain complex connected components Connected component decomposition too coarse Multithreading introduces relations between threads and objects Different threads can access same object Sometimes need correlations across connected components Need more general decompositions
50
50 HeDec: system for Heap Decomposition Parametric: allows experimenting with different decompositions Analysis designer specifies decomposition Subheaps not necessarily disjoint Applicable for states with threads Soundness automatically guaranteed for Any decomposition specification Any transformer specification
51
51 Space of heap abstractions Disjunctive shape abstractions Canonical heap abstraction [Sagiv et al., TOPLAS 02] (cyclic) list abstraction [M. et al., VMCAI 05] Independent attribute shape analysis [Sagiv et al., TOPLAS 98] Connected component decomposition [M. et al., TACAS 07] Parametric heap decomposition [M. et al., SAS 08]
52
52 Application: thread-modular shape analysis for linearizability
53
53 Concurrent heap [Yahav, POPL ‘01] Represent threads and objects 3-Valued structure Top x t n pc=7 pc=14 t thread object with program counter thread-local variable list field list object
54
54 Concurrent heap [Yahav, POPL ‘01] Represent threads and objects 3-Valued structure Formula in subset of FO TC [Yorsh et al., TOCL ‘07] Top x t n pc=7 pc=14 t v1v1 v2v2 tr 1 tr 2 pc(tr 1 )=7 pc(tr 2 )=14… v 1,v 2. t(tr 1,v 1 ) x(tr 1,v 2 ) t(tr 2,v 1 ) n(v 2,v 1 )…
55
55 Select subheaps Parametrically State-sensitive selection Top x t n pc=7 pc=14 t pc(tr 1 )=7 pc(tr 2 )=14… v 1,v 2. t(tr 1,v 1 ) x(tr 1,v 2 ) t(tr 2,v 1 ) n(v 2,v 1 )… v1v1 v2v2 tr 1 tr 2
56
56 Abstraction by decomposition Represent a heap as a conjunction of subheaps Subheaps overlap Top x t n pc=7 pc(tr 1 )=7 v 1. t(tr 1,v 1 ) x(tr 1,v 2 ) n(v 2,v 1 ) … pc(tr 2 )=14 v 2. t(tr 2,v 1 ) … Top pc=14 t v1v1 tr 2 v1v1 v2v2 tr 1
57
57 Intuitive meaning of subheaps Top x t n pc=7 Top pc=14 t ? ? ? ? ? pc=?? tn n n
58
58 Thread-modular analysis Single global resource invariant [Flanagan & Qadeer, SPIN 03] pc=1 Separated resource invariants [Gotsman et al., PLDI 07] Coarse-grained concurrency pc=1 Non-disjoint resource invariants [M. et al., SAS 08] Fine-grained concurrency pc=1
59
59 Toy example threadProc() { Object *x=NULL, *y=NULL; [1] x = new Object(); [2] y = x; [3] assert(x == y); g = x; [4] assert(g != NULL); } thread-local invariant non thread-local invariant Object *g = NULL; // global variable
60
60 Toy example (one thread) x y pc=1 g NULL x y pc=2 g NULL x y pc=3 g NULL x y pc=4 g NULL threadProc() { Object *x=NULL, *y=NULL; [1] x = new Object(); [2] y = x; [3] assert(x == y); g = x; [4] assert(g != NULL); } Object *g = NULL; // global variable
61
61 Toy example (one thread) threadProc() { Object *x=NULL, *y=NULL; [1] x = new Object(); [2] y = x; [3] assert(x == y); g = x; [4] assert(g != NULL); } Object *g = NULL; // global variable x y pc=1 g NULL x y pc=2 g NULL x y pc=4 g NULL x y pc=3 g NULL
62
62 Toy example (one thread) pc = 1 x = y = g = NULL pc = 2 x NULL y = g = NULL pc = 3 x = y NULL g =NULL pc = 4 x = y = g g NULL What about an unbounded number of threads? threadProc() { Object *x=NULL, *y=NULL; [1] x = new Object(); [2] y = x; [3] assert(x == y); g = x; [4] assert(g != NULL); } Object *g = NULL; // global variable
63
63 State with unbounded number of threads x y pc=1 x y pc=2 NULL x y pc=1 x y pc=2 x y pc=3 x y x y pc=4 g x y x y NULL
64
64 Conflate threads at same location x y pc=1 x y pc=2 x y pc=1 x y pc=2 x y pc=3 x y x y pc=4 g x y x y NULL
65
65 x y pc=1 x y pc=2 x y pc=3 x y pc=4 g threadProc() { Object *x=NULL, *y=NULL; [1] x = new Object(); [2] y = x; [3] assert(x == y); g = x; [4] assert(g != NULL); } Lost correlations between local variables of same thread Executed by many threads x any y may not be aliased x==y cannot be proved NULL Bounded abstract state
66
66 pc(t) = 1 … pc(t) = 2 … pc(t) = 3 x(t) = y(t) … - pc(t) = 4 x(t) = y(t) g NULL - pc(t) = 4 x(t) = y(t) = g g NULL … tt threadProc() { Object *x=NULL, *y=NULL; [1] x = new Object(); [2] y = x; [3] assert(x == y); g = x; [4] assert(g != NULL); } Object *g = NULL; // global variable Each disjunct represents an abstraction of state from the perspective of one thread Lost information: number of threads Indexed predicate Quantified (indexed) abstraction
67
67 x y pc=1 x y pc=2 x y pc=1 x y pc=2 x y pc=3 x y x y pc=4 g x y x y Intuition for quantified abstraction NULL
68
68 x y pc=4 g tt Information maintained (dis)equalities between local variables of each thread and global variables (and NULL) Information lost Number of threads (dis)equalities between variables of different threads … pc(t) = 4 x(t) = y(t) = g g NULL … Intuition for quantified abstraction x pc=1 pc=2 pc=3 pc=4 y
69
69 Invalid assertion threadProc() { Object *x=NULL, *y=NULL; [1] x = new Object(); [2] y = x; [3] assert(x == y); g = x; [4] assert(g != NULL); [5] assert(g == x); } Object *g = NULL; // global variable
70
70 x y pc=1 NULL x y pc=2 NULL x y pc=3 Abstract error trace x y pc=1 NULL [1] x = new Object(); x y pc=1 NULL x y pc=2 NULL [2] y = x; g = x; x y pc=4 g x y x y pc=1 NULL x y pc=2 NULL x y pc=3 scheduled thread non-scheduled thread assert(g == x) doesn’t hold
71
71 [1] void push(Stack *S, data_type v) { [2] Node *x = alloc(sizeof(Node)); [3] x->d = v; [4] do { [5] Node *t = S->Top; [6] x->n = t; [7] } while (!CAS(&S->Top,t,x)); [8] } [9] data_type pop(Stack *S){ [10] do { [11] Node *t = S->Top; [12] if (t == NULL) [13] return EMPTY; [14] Node *s = t->n; [15] data_type r = t->d; [16] } while (!CAS(&S->Top,t,s)); [17] return r; [18] } Prove linearizability for an unbounded number of threads Non-blocking stack [Treiber, 1986]
72
72 Linearizability in a nutshell Correctness criterion for concurrent data structures [Herlihy & Wing, TOPLAS 1990] Provides illusion that each operation is atomic Linearization point Concurrent execution “equivalent to” some legal sequential execution time S.push(x) S.push(y) S.pop(x) S.pop(y) time
73
73 Delta abstraction [Amit et al. CAV 07] Tracks bounded differences between concurrent and sequential execution Limited to bounded number of threads Linearization points at successful CAS operations Use special Corr predicate to tracks differences “Correlated objects” Tracks correlations between all threads Feasible up to 4 threads
74
74 Our approach Tracks bounded differences between concurrent and sequential execution per thread Handles unbounded number of threads Linearization points at successful CAS operations Tracks enough correlations to detect successful CAS operations Abstracts correlations between threads Thread-modular characteristics
75
75 Decomposition for linearizability For each thread t maintain Objects pointed-to by local variables Objects pointed-to by global variables CAS(&S->Top,t,x) Corr component Objects pointed-to by global variables Correlated objects Top n x n x t s t t n n pc=7 pc=6 pc=14 pc=16 t corr Overlapping subheaps
76
76 M1M1 M2M2 M3M3 M4M4 Decomposing concurrent states Information lost Number of threads Correlations between thread- local variables of different threads Top x t n pc=7 corr Top n x t pc=6 corr Top pc=14 t corr Top t s n pc=16 corr Top n n n corr M5M5 Information maintained Correlations between thread-local variables of every thread Correlations between thread-local variables and global variables Thread’s local mutations Thread-modular analysis characteristics
77
77 Detecting linearization points Top x t n pc=7 Top n x t pc=6 corr ? ? ? t n n pc=14 pc=6 pc=9 pc=7 pc=15 corr ? ? ? pc=6 pc=9 ? ? corr CAS(Top,t,x) succeeds CAS(Top,t,x) fails
78
78 Verified Programs#statestime (sec.) Treiber’s stack [1986] 764 7 Two-lock queue [Doherty & Groves, FORTE’04] 3,415 17 Non-blocking queue [Michael & Scott, PODC’96] 10,333 252 Experimental results First automatic verification of linearizability for unbounded number of threads Utilized properties Mutations occur near data structure access points Bounded #mutations per data structure operation per thread
79
79 Conclusion Partially disjunctive shape abstraction promising technique Decomposition can be used for more “modular” analysis Parametric system Handle combination of Unbounded number of threads Dynamically-allocated memory Automatically proves linearizability Also useful for sequential programs
80
80 Other thesis results Partial isomorphism join [M. et al., SAS 04] The choice abstraction of TVLA users 100X speedups Precise abstractions for singly-linked lists [M. et al., VMCAI 05] Encoded in predicate abstraction Encoded in Canonical heap abstraction Employed by [Anand et al., SPIN 03] [Distefano et al., TACAS 06] [Gotsman et al., SAS 06] Extended to trees [Lev-Ami et al., CAV 07]
81
81 Other results Postmortem symbolic evaluation [M. et al., FSE 04] Explain program failures using crash dump information and backward analysis Combining Shape Analyses by Intersecting Abstractions [Arnold et al., VMCAI 06] Meet algorithm for 3-Valued structures Theoretical framework for counterexample- guided abstraction refinement [M. et al., Reinhard Wilhelm Festschrift 07]
82
82 Collaborators Stephan Adams [MSR] Gilad Arnold [UCB] Josh Berdine [MSR] Byron Cook [MSR] Manuvir Das [MSR] Tal Lev-Ami [TAU] John Field [IBM] Deepak Goyal [IBM] Tom Henzinger [EPFL] Ramalingam [MSR] Manu Sridharan [UCB] Ran Shaham [TAU] Eran Yahav [IBM] Zhe Yang [MSR]
83
83 Thank you Mooly Sagiv [TAU] Ramalingam [MSR] Daphna Amit [TAU] Eran Yahav [IBM] Greta Yorsh [IBM] Noam Rinetzky [QMUL] Nurit Dor [TAU] Ohad Shacham [TAU] Ran Shaham [TAU] Tal Lev-Ami [TAU] Tom Reps [WU] Reinhard Wilhelm [Saarbrucken] Tom Ball [MSR] Shuvendu Lahiri [MSR] Nir Andelman [Google]
84
84 Related work Partial isomorphism join Partial isomorphism join for symbolic heaps [Yang et al., CAV 08] Heap analysis by separation [Yahav & Ramalingam, PLDI 04] [Hackett & Rugina, POPL 05] Decompose verification problem itself and conservatively approximate contexts Predicate/variable clustering [Clarke et al., CAV 00] Statically-determined decomposition Cartesian transformers [Ball et al., TACAS 01] Handling concurrency with shape for an unbounded number of threads Thread-modular analysis [Gotsman et al., PLDI 07] Rely-guarantee [Vafeiadis et al., SAS 07] …
85
85 Space of heap abstractions Disjunctive shape abstractions Canonical heap abstraction [Sagiv et al., TOPLAS 02] (cyclic) list abstraction [M. et al., VMCAI 05] Independent attribute shape analysis [Sagiv et al., TOPLAS 98] Connected component decomposition [M. et al., TACAS 07] Parametric heap decomposition [M. et al., SAS 08] Partial isomorphism join [M. et al., SAS 04]
86
86 Specifying heap decompositions Use unary predicates to define decomposition (for fixed num of components) p 1 (v), p 2 (v),… Full heap p 1 (v) p 2 (v) decompose Subheaps p 2 (v)
87
87 Composing abstractions: take 1 h1t1... h2t2... h1t1 h2t2 h1t1 1 h2t2 1 Concrete domain: concrete heaps Decomposed subheaps Decomposed bounded subheaps decompose compose bound explode h1t1 h2t2 h2t2... h1t1... h1t1 >1 h2t2 >1
88
88 Composing abstractions: take 2 h1t1... h2t2... h1t1 h2t2 h1t1 h2t2 h1t1 h2t2 >1 1 1 Concrete domain: concrete heaps Bounded heaps Decomposed bounded subheaps bound explode decompose compose h1t1 1 h2t2 1 h1t1 >1 h2t2 >1
89
89 Unbounded decompositions Use indexed binary predicates to define decomposition Decomposition defined relative to object of interest t p(t,v) Full heap p(t,v) decompose Subheaps p(t,v) tt
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.