Download presentation
Presentation is loading. Please wait.
Published byAnissa Ross Modified over 8 years ago
1
Static Analysis of Concurrent Programs Mooly Sagiv
2
Why Concurrent Programs Partial execution order More efficient implementations –Multicore machines Distributed environments
3
Challenges in Concurrent Programs Hard to define the semantics Hard to debug –Assertion checking /partial does not suffice –Many potential executions –Testing is very hard –Reproducing bugs is hard Hard to verify
4
Java Concurrency JVM supports threads of execution –Many threads can be executed “simultaneously” –Communicate via shared memory –Synchronize activities using locks –Both threads and locks are objects Standard methods for efficient transfer of control –wait –notify –… Special rules about allowed orders of executions
5
Main memory write read lock working memory Thread engine assign use store load lock Java Memory Model unlock working memory Thread engine assign use store load unlock lock
6
Java code fragment synchronized(p) { p.y = 2; } a = p.x; b = p.y; c = p.y; synchronized(p) { p.y = 3; p.y = 100; } p.x = 1; [p.x 0, p.y 0]
7
Plan Correctness Criteria Alias analysis A Reference Solution –Checking Linerizability More scalable solutions –Flow insensitive solutions –Thread modular analysis –Cartesian (Independent Attribute) abstraction
8
Correctness Criteria Partial correctness (assertion checking) –No runtime errors –No memory leaks Absence of deadlocks Termination Absence of dataraces Linearizability
9
Deadlocks Happens when two or more competing threads are waiting for the other to finish, and thus neither ever does lock(l1); lock(l2); … unlock(l2); unlock(l1); lock(l2); lock(l1); … unlock(l1); unlock(l2);
10
Dataraces Occurs when two threads access the same resource –At least one of the accesses are write –No mechanism to prevent order conflicts
11
A Simple Example x := y;y := y +1;
12
Java code fragment synchronized(p) { p.y = 2; } a = p.x; b = p.y; c = p.y; synchronized(p) { p.y = 3; p.y = 100; } p.x = 1; [p.x 0, p.y 0]
13
No Datarace lock(l); v := v+1; unlock(l); lock(l); v := v +1; unlock(l);
14
Concurrency and Alias Analysis sync(e1) { e2.f = } sync(e3) { … = e4.f } Different locks Same Object
15
Programs and Properties Concurrent programs Unbounded number of threads –parametric systems Unbounded number of objects Pointers and destructive updates Memory safety –Absence of null dereferences –Absence of memory leaks Preservation of data structure invariants Linearizability User-specified invariants 15
16
A Generic Framework for Verifying Concurrent Programs Eran Yahav POPL’01
17
Main Ideas An interleaving semantics for Java –A program configuration encodes global store program-location of every thread status of locks and threads First-order logical structures used to represent program configurations Use TVLA to obtain a static analyzer Works well for tiny programs
18
Configurations Predicates model properties of interest –eq(v 1,v 2 ) –is_T(v) –{ at[lab](t) : lab Labels } –{ rv[fld](o 1,o 2 ) : fld Fields } –heldBy(l,t), blocked(t,l), waiting(t,l) Can use the framework with different predicates
19
Structural Operational Semantics An action consists of: –precondition formula –update formulae Precondition formula may use a free variable t s for “currently scheduled” thread Semantics is non-deterministic
20
Structural Operational Semantics - actions lock(v) t t s : rval[v](t s,l) held_by(l,t) held_by’(l 1,t 1 ) = held_by(l 1,t 1 ) (l 1 = l t 1 = t s ) blocked’ (t 1,l 1 ) = blocked(t 1,l 1 ) ((l 1 l) (t 1 t s )) precondition predicate update
21
Safety Properties Configuration-local property as logical formula Example: no total deadlock t, l b : is_thread(t) blocked(t, l b ) t 1,t 2 : (t 1 t 2 ) (at[l crit ](t 1 ) at[l crit ](t 2 )) Example: mutual exclusion
22
Configurations – Example at[l_C] rval[myLock] held_by at[l_1] rval[myLock] at[l_0] at[l_1] rval[myLock] blocked l_0: while (true) { l_1: synchronized(myLock) { l_C:// critical actions l_2: } l_3: }
23
Concrete Configuration at[l_C] rval[myLock] held_by at[l_1] rval[myLock] at[l_0] at[l_1] rval[myLock] blocked
24
Abstract Configuration at[l_C] rval[myLock] held_by blocked at[l_1] rval[myLock] at[l_0]
25
Abstract Interpretation at[l_0] rval[myLock] l_0: while (true) { l_1: synchronized(myLock) { l_C:// critical actions l_2: } l_3: }
26
Abstract Interpretation rval[myLock] at[l_1] rval[myLock] at[l_0] l_0: while (true) { l_1: synchronized(myLock) { l_C:// critical actions l_2: } l_3: }
27
Abstract Interpretation rval[myLock] at[l_1] rval[myLock] at[l_0] l_0: while (true) { l_1: synchronized(myLock) { l_C:// critical actions l_2: } l_3: }
28
Abstract Interpretation at[l_C] rval[myLock] held_by at[l_1] rval[myLock] at[l_0] rval[myLock] l_0: while (true) { l_1: synchronized(myLock) { l_C:// critical actions l_2: } l_3: }
29
Abstract Interpretation at[l_C] rval[myLock] held_by blocked at[l_1] rval[myLock] at[l_0] rval[myLock] at[l_1] l_0: while (true) { l_1: synchronized(myLock) { l_C:// critical actions l_2: } l_3: } rval[myLock]
30
Abstract Interpretation at[l_C] rval[myLock] held_by blocked at[l_1] rval[myLock] at[l_0] rval[myLock] l_0: while (true) { l_1: synchronized(myLock) { l_C:// critical actions l_2: } l_3: }
31
Examples Verified ProgramProperty twoLock QNo interference No memory leaks Partial correctness Producer/consumerNo interference No memory leaks Apprentice Challenge Counter increasing Dining philosophers with resource ordering Absence of deadlock MutexMutual exclusion Web ServerNo interference
32
Scalability The number of abstract configurations is doubly exponential in the program size Interleaving semantics quickly leads to state explosion
33
Techniques for Scalability Courser abstractions –Refinement Program restrictions Limited semantics Specialization Unsoundness
34
Flow Insensitive Analysis Ignore control flow statements Obtain a sound solution w.r.t. all interleavings But can it be precise enough? –Initializations –Strong updates –Object sensitivity –Context sensitivity
35
Critical Section Example l_0: while (true) { l_1: synchronized(myLock) { l_C:// critical actions l_2: } l_3: }
36
Thread Modular Shape Analysis Alexey Gotsman PLDI’07
37
Is this a well-formed cyclic doubly-linked list? 37
38
Main Ideas Compile-time names for threads and locks Static association of the locks and parts of the heap Analyze the behavior of every thread separately with a resource invariant describing the state of others –Break the heap into two parts Overapproximate local and resource invariants Prove the absence of dataraces
39
A motivating example(unrealistic) class List { public List n; public int d; } List g; void producer(){ List p; while (1) { … create a list in p synchronized (g} { g = p; p = null ; } void consumer(){ List c; while (1) { synchronized (g} { c = g; g = null ; } … consume c; }
40
A motivating example(producer) g == null while Create A list p lock(g); g=p; p=null; p == null p ==list g == null p ==list g==p p==list unlock(g); p == null g==list
41
A motivating example(producer) g == null g==list while Create A list p lock(g); g=p; p=null p == null p ==list g == null p ==list g==p p==list unlock(g); p == null g==list p == null
42
A motivating example(producer) g == null g==list while Create A list p lock(g); g=p; p=null p == null p ==list (g == null g==list) p ==list g==p p==list unlock(g); p == null g==list p == null Potential memory leak
43
A motivating example(consumer) g == null g==list while lock(g); c=g; g=null c == null c==null (g == null g==list) unlock(g); consume(c) c==g (g == null g==list) g==null (c == null c==list) c == null c==list
44
A Separation Domain is the usual lattice *: D D D is a partially ordered commutative monoid –* is associative and commutative –* has the unit element e –* is monotone
45
Locality A separated domain A function f: D D is local if for all u,v: f(u * v) f(u) * v
46
Relating Concrete and Abstract Separated Domains A separated concrete domain A separated abstract domain A concretization : A C such that – is monotone –Abstract transformers over-approximate concrete ones – is a homomorphism between abstract and concrete monoids a, b: (a * A b) = (a) * C (b)
47
Decomposition Based Shape Analysis Roman Manevich
48
Thread-Modular Analysis Abstract away the correlations between local states of different threads No correlations between program counters Cartesian Abstraction Information maintained Correlations between the local state and global state of each thread “The quadratic cost of computing transformers can be greatly reduced…” [Flanagan & Qadeer SPIN, 2003] Naturally handles unbounded number of threads 48
49
A Singleton Buffer 49 Boolean empty = true; Object b = null; produce() { 1: Object p = new(); 2: await (empty) then { b = p; empty = false; } 3: } consume() { Object c; 4: await (!empty) then { c = b; empty = true; } 5: use(c); 6: dispose(c); 7: } Safe Dereference No Double free b=null;
50
P1 empty 3: p1p1 b empty 5: c2c2 b empty 5: c1c1 b Thread-Modular Abstraction 50 empty 3: p1p1 b 5: empty 5: b emptyb p1p1 3: p2p2 c1c1 5:c2c2 emptyb p1p1 3: p2p2 c1c1 5:c2c2 empty 3: p1p1 b empty 5: c2c2 b empty 3: p1p1 b 5: empty 3: p2p2 b empty 3: b P2 C1C2 empty 5: c1c1 b empty 5: b
51
P1 empty 3: p1p1 b empty 5: c2c2 b empty 5: c1c1 b 51 empty 3: p1p1 b 5: empty 5: b emptyb p1p1 3: p2p2 c1c1 5:c2c2 emptyb p1p1 3: p2p2 c1c1 5:c2c2 empty 3: p1p1 b empty 5: c2c2 b empty 3: p1p1 b 5: empty 3: p2p2 b empty 3: b P2 C1C2 empty 5: c1c1 b empty 5: b emptyb p1p1 3: p2p2 c1c1 5:c2c2
52
P1 empty 3: p1p1 b empty 5: c2c2 b c1c1 b Thread-Modular Abstraction 52 empty 3: p1p1 b 5: b emptyb p1p1 3: p2p2 c1c1 5:c2c2 emptyb p1p1 3: p2p2 c1c1 5:c2c2 3: p1p1 b !empty 5: c2c2 b 3: p1p1 b 5: empty 3: p2p2 b empty 3: b P2 C1C2 empty 5: c1c1 b empty 5: b 3: p2p2 b b !empty not all combinations are feasible
53
Partial Abstract Interpretation P1P2 P3 C1 C2 C3 4 : 53 4: C1: await !empty then { c 1 =b; empty=true;} 4: C2: await !empty then { c 2 =b; empty=true;} 5: C1: use(c 1 ); dispose(c 1 ) 5: empty c1c1 b b 4: b b 5: empty c2c2 b 2: p2p2 b p1p1 b 3: b p3p3 empty 5: b c2c2 empty 7: b c1c1 Potential Double Free!!! !empty 5: C2: use(c 2 ); dispose(c 2 )
54
A Singleton Buffer 54 Boolean empty = true; Object b = null; produce() { 1: Object p = new(); 2: await (empty) then { b = p; empty = false; } 3: } consume() { Object c; 4: await (!empty) then { c = b; empty = true; } 5: use(c); 6: dispose(c); 7: } Safe Dereference No Double free b=null;
55
Thread-Modular Analysis Abstract away the correlations between local states of different threads No correlations between program counters Cartesian Abstraction Information maintained Correlations between the local state of each thread and the globals Scales with the number of threads Handles unbounded number of threads But limited precision 55
56
Increasing Precision Enforce program restrictions Limited aliasing Ownership relations Limited concurrency Enhanced analysis Global instrumentation Separation Domains [Gotsman et. al. PLDI’07] Semi-Thread Modular Analysis [Segalov et. al., TR, Berdine et. al. CAV’08] 56
57
Thread-Modular Analysis 57 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 [Roman’s work] Fine-grained concurrency pc=1
58
Semi-Thread-Modular Analysis M. Segalov, T. Lev-Ami, R. Manevich, G. Ramalingam, M. Sagiv 58 Thread Quantification for Concurrent Shape Analysis J. Berdine, T. Lev-Ami, R. Manevich, G. Ramalingam, M. Sagiv CAV’08
59
Main Results A refinement of thread-modular analysis Not fully modular Precise enough to prove properties of fine- grained concurrent programs Were not automatically proved before Two effective methods for efficiently computing transformers Summarizing Effects Summarizing Abstraction On a concurrent set imp. speedup is x34! 59
60
Semi-Thread-Modular Analysis Abstract away correlations between local states of more than two threads Information maintained Correlations between the local state of each thread and the global state May-correlations between local states of every pair of threads Not necessarily symmetric 60
61
6: 4: empty c1c1 c2c2 c3c3 c4c4 6:4:6:4: empty c1c1 c2c2 c3c3 c4c4 6:4: 6: empty c1c1 c2c2 c3c3 c4c4 Semi-Thread-Modular Abstraction C1,C2 6: empty c1c1 c2c2 6: empty c1c1 c2c2 6: empty c1c1 c3c3 6: empty c1c1 c3c3 6: empty c1c1 c4c4 6: empty c1c1 c4c4 6: empty c2c2 c1c1 4: empty c2c2 c1c1 4: empty c2c2 c3c3 6: empty c2c2 c3c3 4: empty c2c2 c4c4 6: empty c2c2 c4c4 C1,C4 C1,C3 C2,C1 C2,C3C2,C4 4: empty c2c2 c3c3 4: empty c2c2 c4c4 … 61
62
6: 4: C1,C2 empty c1c1 c2c2 c3c3 c4c4 6:4:6:4: empty c1c1 c2c2 c3c3 c4c4 6:4: 6: empty c1c1 c2c2 c3c3 c4c4 6: empty c1c1 c2c2 Semi-Thread-Modular Concretization 6: empty c1c1 c2c2 6: empty c1c1 c3c3 6: empty c1c1 c3c3 6: empty c1c1 c4c4 6: empty c1c1 c4c4 6: empty c2c2 c1c1 4: empty c2c2 c1c1 4 c2c2 c3c3 6: empty c2c2 c3c3 4: empty c2c2 c4c4 6: empty c2c2 c4c4 C1,C4 C1,C3 C2,C1 C2,C3C2,C4 4: empty c2c2 c3c3 4: empty c2c2 c4c4 … 6:4: empty c1c1 c2c2 c3c3 c4c462
63
Worst-Case Complexity Full state analysis Shared state – G,Local state – L tid State space = (G L 1 ... L n ) #states: O(|G| |L| n ) Thread-modular analysis State space = (G L 1 ) ... (G L n ) #states: O(n |G| |L|) Semi-thread-modular analysis State space = (G L 1 L 2 ) ... (G L n-1 L n ) #states: O(n |G| |L| 2 ) 63
64
Point-wise Transformer dispose(c 1 ) 64 empty 6: c1c1 c3c3 b 6: C1: dispose(c 1 ) empty 7: c1c1 c3c3 b
65
Point-wise Transformer dispose(c 1 ) 65 empty 7: c2c2 c3c3 b empty 6: c2c2 c3c3 b c1c1 c3c3 ?? ?: 6: C1: dispose(c 1 ) is this command safe in this configuration? missing information on c 1
66
Most-Precise Transformer 66 abstract element concrete element ’’ most-precise abstract semantics [CC’79] statement st operational semantics statement st concrete element abstract element ’’
67
Sound Transformer 67 abstract element most-precise abstract semantics [CC’79] statement st “simple” abstract semantics statement st abstract element ’’ ’’ refined element partial concretization
68
Partial Concretization Based Transformer 68 factoids abstract semantics statement st exec statement st 3-thread substate proj factoids substates 3-thread substate
69
Transformer for Concurrent Systems 69 factoids Chose 1 st component as executing thread statement st Chose other component statement st 3-thread substate proj factoids substates 3-thread substate factoids TR (F) = { : F, } , : f 1, f 2, f 3, f 4 F: substates(f 1, f 2, f 3, f 4 ),
70
Partial Concretization empty 6: c1c1 c2c2 c3c3 empty 6: c2c2 c2c2 empty 6: c1c1 c2c2 c3c3 empty 4: c3c3 c2c2 empty 6: c4c4 empty 6: c2c2 c2c2 c4c4 empty 4: c4c4 c2c2 empty 6: c1c1 c4c4 empty 6: c1c1 c4c4 empty 6: c1c1 c3c3 empty 6: c1c1 c3c3 C1,C2 C1,C4 C1,C3 C2,C3C2,C4 empty 6: c1c1 c2c2 empty 4: c1c1 c2c2 C2,C1 ….. 70 C1: Executing C2: Tracked C3: Other
71
Partial Concretization(Substates) empty 6: c1c1 c2c2 empty 6: c1c1 c2c2 empty 6: c1c1 c3c3 empty 6: c1c1 c3c3 empty 6: c3c3 empty 6: c2c2 c2c2 c3c3 empty 4: c3c3 c2c2 empty 6: c1c1 c2c2 empty 4: c1c1 c2c2 empty c1c1 c2c2 6:4: c3c3 empty c1c1 c2c2 6: c3c3 71 C1,C2C1,C3 C2,C1 C2,C3
72
6: C1: dispose(c) (exec) 72 empty c1c1 c2c2 6: c3c3 empty c1c1 c2c2 6:4: c3c3 6: empty c1c1 c2c2 6: c3c3 7: empty c1c1 c2c2 7:4: c3c3
73
73 empty c1c1 c2c2 6: c3c3 7: empty c1c1 c2c2 7:4: c3c3 empty 6: c2c2 c3c3 C2,C3C2,C1 empty 6: c1c1 c2c2 6: C1: dispose(c) (project) empty 4: c2c2 c3c3 empty 4: c1c1 c2c2
74
Reducing Quadratic Factors 74 Exploit redundancies in the action Cannot affect locals of other threads Use asymmetry between the two abstraction Can prove no loss of information Summarizing Effects Apply aggressive abstraction to the executing threads Summarizing Abstraction TR (F) = { : F, } , : f 1, f 2, f 3, f 4 F: substates(f 1, f 2, f 3, f 4 ),
75
Other Methods for Static Analysis of Concurrency Start by sequential analysis and then coarsen abstractions Rely/Guarantee reasoning … 75
76
Summary Static analysis of concurrency is interesting Thread modular analysis yields impressive results for well behaved coarse-grained concurrency Decompositions can be applied to scale abstractions even for fine-grained concurrency
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.