Presentation is loading. Please wait.

Presentation is loading. Please wait.

Thread-modular Abstraction Refinement Thomas A. Henzinger, et al. CAV 2003 Seonggun Kim KAIST CS750b.

Similar presentations


Presentation on theme: "Thread-modular Abstraction Refinement Thomas A. Henzinger, et al. CAV 2003 Seonggun Kim KAIST CS750b."— Presentation transcript:

1 Thread-modular Abstraction Refinement Thomas A. Henzinger, et al. CAV 2003 Seonggun Kim KAIST CS750b

2 2/28 Abstract of this paper We present an algorithm called Tar (“Thread-modular Abstraction Refinement") for model checking safety properties of concurrent software. The Tar algorithm uses thread-modular assume-guarantee reasoning to overcome the exponential complexity in the control state of multithreaded programs. Thread modularity means that Tar explores the state space of one thread at a time, making assumptions about how the environment can interfere. The Tar algorithm uses counterexample guided predicate-abstraction refinement to overcome the usually infinite complexity in the data state of C programs. A successive approximation scheme automatically infers the necessary precision on data variables as well as suitable environment assumptions. The scheme is novel in that transition relations are approximated from above, while at the same time environment assumptions are approximated from below. In our software verification tool Blast we have implemented a fully automatic race checker for multithreaded C programs which is based on the Tar algorithm. This tool has verified a wide variety of commonly used locking idioms, including locking schemes that are not amenable to existing dynamic and static race checkers such as Eraser or Warlock. Assume-guarantee reasoning Thread-modularity (one thread at a time) The exponential complexity in the control state of mt-programs Needs assumptions about the behavior of other threads Due to interleaving Iteratively weakening the assumptions until fix-point Assumption Inference

3 3/28 Multithreaded Programs Why multithreading?  Performance (esp, response time)  Conceptual simplicity Why not multithreading?  Race hazard  Deadlock Thread Shared Memory x Thread Thread

4 4/28 Race Hazard A thread can be interfered by others 1: bal = getBalance(); 2: bal += deposit; 3: setBalance(bal); 2: bal += deposit; 1: bal = getBalance(); 3: setBalance(bal); 2: bal += deposit; 1: bal = getBalance(); 3: setBalance(bal); balance = 100 deposit = 20 bal = 100 bal = 120 bal = 100 bal = 120 balance = 120

5 5/28 Detecting Race Hazard Critical Section  A piece of code that must not be concurrently accessed by more than one thread Can be detected by safety checking  “Is (T1||T2) reachable to states satisfying (pc1  Crit  pc2  Crit) ?” No  safe, Yes  unsafe But, it may be intractable

6 6/28 Curse of Interleaving Need to abstract away other threads  Divide and Conquer (one thread at a time)  Can we do the abstraction a priori? B3 A2 B1 A3 B2 A1 B3 A2 B1 A3 B2 A1 B3 A2 B1 A3 B2 A1 B3 A2 B1 A3 B2 A1 B3 A2 B1 A3 B2 A1 B3 A2 B1 A3 B2 A1 … State Explosion n k (n statements, k threads)

7 7/28 Naïve Thread-modular Analysis Conservative (pessimistic) Assumption  “Others can access shared resources anytime” safe Simple, But rarely happens

8 8/28 Assume-Guarantee Reasoning Assume-Guarantee reasoning 1. Make an assumption 2. Use the assumption to prove required properties 3. Ensure the assumption is correct S 1, S 2 : sub-systems P 1, P 2 : sub-properties S 1 v P 1 S 2 v P 2 S 1 u S 2 v P 1 u P 2 S 1 v P 1 P 1 u S 2 v P 2 S 1 u S 2 v P 1 u P 2 P 2 u S 1 v P 1 P 1 u S 2 v P 2 S 1 u S 2 v P 1 u P 2 Prove: S 1 u S 2 v P 1 u P 2 Divide and Conquer Assume-Guarantee

9 9/28 Circular Assume-Guarantee Cyclic Guarantee  To guarantee assuming P2 is correct, we need to guarantee assuming P1 is correct, vice versa  Cycle-breaking condition is needed (beyond this paper) Is it sound? Is it complete?  Not sound, not complete for general cases  Sound, but not complete for safety properties (beyond this paper) P 2 u S 1 v P 1 P 1 u S 2 v P 2 S 1 u S 2 v P 1 u P 2 Circular Assume-Guarantee  u S 1 v   u S 2 v  S 1 u S 2 v  u 

10 10/28 Thread-modular AG Reasoning A form of assume-guarantee reasoning P = S 1 | S 2 | … | S n For each thread S i, specify two actions  A i : an environment assumption of S i Transitions that may be performed by other threads  G i : a guarantee of S i Transitions of S i under A i that can be seen by other threads Ensuring the assumption  Check whether G i is stronger than A j for all j, j  i

11 11/28 safe Use Summaries ( “ Assume ” ) safe A

12 12/28 safe Verify Summaries ( “ Guarantee ” ) µ µ safe G

13 13/28 Assume-Guarantee Reasoning µ safe µ

14 14/28 T-M Abstraction Refinement Step0: Seed Assumption  Set the assumption for each thread to false (  ) Step1: Reachability Analysis (same as LA)  Compute an abstraction R i of the reachable states of each thread i, based on the current assumptions about the behavior of the other threads Step2: Counterexample Analysis (same as LA)  Check if R i contains error states Yes: do trace analysis and abstraction refinement; goto step0 No: goto step3 Step3: Guarantee Assumptions  Check if the assumptions are sound Yes: report “safe” No: update the assumptions w.r.t. the R i ; goto step1 allows no transition to other threads allows transitions R i to other threads

15 15/28 Iter1: Build Summary A Reach Grap h G ; µ ; Summarize A Reach Grap h No Race Race Trace Local Predicate - Cuts locally infeasible paths - Invisible to other threads - Quantified away

16 16/28 Iter1: Trace Analysis Trace FeasibleInfeasible Refine using Trace Add new predicates Report Trace Interleaved sequence of threads’ ops

17 17/28 Iter2: Build Summary A Reach Graph G µ ; Summarize A Reach Graph G µ Summarize A Reach Graph G µ Summarize ;

18 18/28 Context arrives at Fix-point A Reach Graph G µ Summarize Shared Memory Assume-Guarantee No Race

19 19/28 Example: Producer-Consumer Shared Variables: data, flag Error State: pc p = 3  pc c = 3 Initial State: pc p = 1  pc c = 1  flag = 0 Implicit Local Predicate: pc p, pc c Thread Producer 1: while(1) { 2: while(flag != 0) {}; 3: data = produce_data(); 4: flag = 1; } Thread Consumer 1: while(1) { 2: while(flag != 1) {}; 3: copy = data; 4: flag = 0; }  P  C, P, C  !P  !C

20 20/28 Iteration 1-1 Thread Producer 1: while(1) { 2: while(flag != 0) {}; 3: data = produce_data(); 4: flag = 1; }   Reach Graph !P P Sum. µ  Thread Consumer 1: while(1) { 2: while(flag != 1) {}; 3: copy = data; 4: flag = 0; }   Reach Graph !C C Sum. µ  !P P !C C

21 21/28 Iteration 1-2 Thread Producer 1: while(1) { 2: while(flag != 0) {}; 3: data = produce_data(); 4: flag = 1; } R. G. Thread Consumer 1: while(1) { 2: while(flag != 1) {}; 3: copy = data; 4: flag = 0; } R. G. !C C !P P !P  !C!P  C PCPCP!CP!C !P  !C!P  C !P  !C!P  C !C  !P!C  P CPCPC  !P !C  !P!C  P !C  !P!C  P Trace Analysis Add flag

22 22/28 Iteration 2-1 Thread Producer 1: while(1) { 2: while(flag != 0) {}; 3: data = produce_data(); 4: flag = 1; }   R. G. Thread Consumer 1: while(1) { 2: while(flag != 1) {}; 3: copy = data; 4: flag = 0; }   R. G. S.S. !P P  !F !P !P  F !C CFCF !C  !F S.S. !P P  !F !P  F !C CFCF !C  !F µ  µ 

23 23/28 Iteration 2-2 Thread Producer 1: while(1) { 2: while(flag != 0) {}; 3: data = produce_data(); 4: flag = 1; } R. G. Sum !P P  !F !P  F !C CFCF !C  !F !P  !C!P  C  F!P  !C  !F !P  !C!P  C  F!P  !C  !F P  !F  !C !P  F  !C!P  C  F!P  !C  !F !P  !C!P  C  F!P  !C  !F P  !F  !C !P  F  !C!P  C  F!P  !C  !F  Same for Consumer

24 24/28 Experimental Result

25 25/28 NO (trace) Thread-modular Analysis Init. Abstraction Preds: P 0 Ctr: k 0 Init. Summary Summary: ; A Reach Graph YES Summarize Safe? G µ ? YES NO Update Summary Refine using Trace Feasible? YES NO Output SAFE No Data Races Output Data Race TRACE ANALYSIS BUILD SUMMARY

26 26/28 Conclusion Thread-Modular Abstraction Refinement  Overcome the exponential complexity in the control state of multithreaded programs Race Detection  Verified a wide variety of commonly used locking idioms Including locking schemes that are not amenable to existing race checkers such as Eraser or Warlock

27 27/28 Pros & Cons Pros  Annotation-free thread-modular analysis  Extends BLAST to concurrent programs Cons  It still needs to compute an interleaving To check if the trace is feasible Does it really reduce the burden of interleaving?

28 28/28 References Some figures and slides come from Ranjit Jhala’s slides  “Three lectures on Lazy Abstraction” #2 http://www.cse.ucsd.edu/~rjhala/blast.html p.2, pp. 12~16  osq.cs.berkeley.edu/retreat03/Jhala-TAR.ppt p6, pp. 8~10


Download ppt "Thread-modular Abstraction Refinement Thomas A. Henzinger, et al. CAV 2003 Seonggun Kim KAIST CS750b."

Similar presentations


Ads by Google