Presentation is loading. Please wait.

Presentation is loading. Please wait.

Race Directed Random Testing of Concurrent Programs KOUSHIK SEN - UNIVERSITY OF CALIFORNIA, BERKELEY PRESENTED BY – ARTHUR KIYANOVSKI – TECHNION, ISRAEL.

Similar presentations


Presentation on theme: "Race Directed Random Testing of Concurrent Programs KOUSHIK SEN - UNIVERSITY OF CALIFORNIA, BERKELEY PRESENTED BY – ARTHUR KIYANOVSKI – TECHNION, ISRAEL."— Presentation transcript:

1 Race Directed Random Testing of Concurrent Programs KOUSHIK SEN - UNIVERSITY OF CALIFORNIA, BERKELEY PRESENTED BY – ARTHUR KIYANOVSKI – TECHNION, ISRAEL

2 Goal Verify Data Races  Automatically  Efficiently  No false alarms  Being able to reproduce races

3 Background

4 Data Race - Definition  Two or more threads access the same memory location concurrently  At least one of the accesses is for writing x=1 if (x==1) … Temporally next to each other

5 Data Race – Another Example Thread 2: X=X+1; Thread 1: X=X+1; What “actually happens” in x=x+1? 1.Read x to tmp 2.Add 1 to tmp 3.Write tmp to X

6 Not a Data Race! Thread 2: Lock(L); X=X+1; Unlock(L); Thread 1: Lock(L); X=X+1; Unlock(L);

7 Multithreaded Testing On One CPU  Lets say we have 2 threads – blue and red.  There is a data race between red 3 and blue 3.  Let’s show a way of running them on 1 CPU that can find the same Data Races that running them on 2 CPUs can. 1 2 3 1 2 3 Data Race

8 Once upon a time… Testing concurrent programs

9 The Simple Traditional Way Repeatedly execute the program with the hope that different test executions will result in different interleavings.

10 Advantages Of The Traditional Way  Inexpensive compared to sophisticated techniques such as model checking and verification

11 Problems With The Traditional Way  Outcome highly dependent on the test environment.  Some interleavings may only occur on heavily-loaded test systems.  Depends on the underlying operating system for thread scheduling  Often ends up executing the same interleaving many times.

12 Simple Randomized Algorithm Simple Scheduler At every state during a concurrent execution –Pick a thread randomly –Execute the next instruction of the thread Slide taken and adapted from the original slides of Koushik Sen for PLDI08

13 Simple Randomized Algorithm Simple Scheduler At every state during a concurrent execution –Pick a thread randomly –Execute the next instruction of the thread Slide taken and adapted from the original slides of Koushik Sen for PLDI08

14 Simple Randomized Algorithm Simple Scheduler At every state during a concurrent execution –Pick a thread randomly –Execute the next instruction of the thread Slide taken and adapted from the original slides of Koushik Sen for PLDI08

15 Simple Randomized Algorithm Simple Scheduler At every state during a concurrent execution –Pick a thread randomly –Execute the next instruction of the thread Slide taken and adapted from the original slides of Koushik Sen for PLDI08

16 Simple Randomized Algorithm Simple Scheduler At every state during a concurrent execution –Pick a thread randomly –Execute the next instruction of the thread Slide taken and adapted from the original slides of Koushik Sen for PLDI08

17 Simple Randomized Algorithm Simple Scheduler At every state during a concurrent execution –Pick a thread randomly –Execute the next instruction of the thread Slide taken and adapted from the original slides of Koushik Sen for PLDI08

18 Problems With Randomized Algorithm  Everything is left to chance – Randomized is not good enough for some code structures What are the chances that we randomly stumble upon the data race here? thread2 { x = x+1; } thread1 { for (i=0; i<1,000,000; ++i); x = x+1; } Data Race

19 Program Analysis Techniques  Very effective in finding data races  Static Analysis - No need to see an actual execution.  Dynamic Analysis - Need to see real concurrent execution. BUT  Often report many data races that are false warnings  Require manual inspection to see if a race is real or not

20 False Positive Example thread2 { 3: if (y == 1) 4: if (x != 1) 5: do something; } thread1 { 1: x = 1; 2: y = 1; } Current Analysis Techniques will report a data race between lines 1 and 7. Initially x = y = 0 Data Race?

21 RaceFuzzer Algorithm – Welcome to the Future

22 First Stage – Find Potential Races  Find Potential Candidates For Races  Use an existing technique to find a set of pairs of state transitions that could potentially race.  At the time of writing the paper an Hybrid Race Detection Algorithm was chosen. But any algorithm that can find races will do.

23 Second Stage – Verify Real Races Key Ideas:  Randomized Scheduler  Racing statements “wait for each other“ to increase chances to be detected.  Remember this example? If only thread2 could wait for the end of the for loop… thread2 { x = x+1; } thread1 { for (i=0; i<1,000,000; ++i); x = x+1; } Data Race

24 RaceFuzzer By Example

25 Definitions  Enabled(s) – not waiting for a lock held by another thread  Alive(s) – have not terminated execution  Execute(s, t) – returns state after executing next statement of t  NextStmt(s, t) – next statement that t will execute

26 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1(); s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); Run ERASER: Statement pair (s5,s6) are in race Slide taken and adapted from the original slides of Koushik Sen for PLDI08

27 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1(); s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); Run ERASER: Statement pair (s5,s6) are in race Slide taken and adapted from the original slides of Koushik Sen for PLDI08

28 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1(); s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); (s5,s6) in race Goal: Create a trace exhibiting the race Slide taken and adapted from the original slides of Koushik Sen for PLDI08

29 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1(); s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); (s5,s6) in race Goal: Create a trace exhibiting the race Slide taken and adapted from the original slides of Koushik Sen for PLDI08 Execution: s1: g1(); s2: g2(); s3: g3(); s4: g4(); s6: if (o1.f==1) s5: o1.f = 1;

30 Input and Initialization 1: Inputs: the initial state s0, a set of two racing statements RaceSet 2: s := s0 3: postponed := ∅ 4: while Enabled(s) != ∅ do 5: t := a random thread in Enabled(s) \ postponed 6: if NextStmt(s, t) ∈ RaceSet then 7: R := Racing (s, t, postponed) 8: if R != ∅ then /* Actual race detected */ 9: print “ERROR: actual race found” 10: /* Randomly resolve race */ 11: if random boolean then 12: s := Execute(s, t) 13: else 14: postponed := postponed ∪ {t } 15: for all t‘ ∈ R do 16: s := Execute(s, t‘) 17: postponed := postponed \{t’} 18: end for 19: end if 20: else /* Wait for a race to happen */ 21: postponed := postponed ∪ {t} 22: end if 23: else 24: s := Execute(s, t) 25: end if 26: if postponed = Enabled(s) then 27: remove a random element from postponed 28: end if 29: end while 30: if Active(s) != ∅ then 31: print “ERROR: actual deadlock found” 32: end if

31 Input and Initialization Inputs:  the initial state s0  a set of two racing statements RaceSet Initialization: 2: s := s0 3: postponed := ∅

32 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1(); s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); Execution: (s5,s6) in race Slide taken and adapted from the original slides of Koushik Sen for PLDI08 Postponed = { }

33 While.. Choose a Random Thread 1: Inputs: the initial state s0, a set of two racing statements RaceSet 2: s := s0 3: postponed := ∅ 4: while Enabled(s) != ∅ do 5: t := a random thread in Enabled(s) \ postponed 6: if NextStmt(s, t) ∈ RaceSet then 7: R := Racing (s, t, postponed) 8: if R != ∅ then /* Actual race detected */ 9: print “ERROR: actual race found” 10: /* Randomly resolve race */ 11: if random boolean then 12: s := Execute(s, t) 13: else 14: postponed := postponed ∪ {t } 15: for all t‘ ∈ R do 16: s := Execute(s, t‘) 17: postponed := postponed \{t’} 18: end for 19: end if 20: else /* Wait for a race to happen */ 21: postponed := postponed ∪ {t} 22: end if 23: else 24: s := Execute(s, t) 25: end if 26: if postponed = Enabled(s) then 27: remove a random element from postponed 28: end if 29: end while 30: if Active(s) != ∅ then 31: print “ERROR: actual deadlock found” 32: end if

34 While.. Choose a Random Thread 4: while Enabled(s) != ∅ do 5: t := a random thread in Enabled(s) \ postponed … 29: end while

35 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1(); s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); Execution: (s5,s6) in race Slide taken and adapted from the original slides of Koushik Sen for PLDI08 Postponed = { }

36 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1(); s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); Execution: (s5,s6) in race Slide taken and adapted from the original slides of Koushik Sen for PLDI08 Postponed = { }

37 Next Statement in a race? 1: Inputs: the initial state s0, a set of two racing statements RaceSet 2: s := s0 3: postponed := ∅ 4: while Enabled(s) != ∅ do 5: t := a random thread in Enabled(s) \ postponed 6: if NextStmt(s, t) ∈ RaceSet then 7: R := Racing (s, t, postponed) 8: if R != ∅ then /* Actual race detected */ 9: print “ERROR: actual race found” 10: /* Randomly resolve race */ 11: if random boolean then 12: s := Execute(s, t) 13: else 14: postponed := postponed ∪ {t } 15: for all t‘ ∈ R do 16: s := Execute(s, t‘) 17: postponed := postponed \{t’} 18: end for 19: end if 20: else /* Wait for a race to happen */ 21: postponed := postponed ∪ {t} 22: end if 23: else 24: s := Execute(s, t) 25: end if 26: if postponed = Enabled(s) then 27: remove a random element from postponed 28: end if 29: end while 30: if Active(s) != ∅ then 31: print “ERROR: actual deadlock found” 32: end if

38 Next Statement in a race? 6: if NextStmt(s, t) ∈ RaceSet then … 23: else 24: s := Execute(s, t) 25: end if

39 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1(); s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); Execution: (s5,s6) in race Slide taken and adapted from the original slides of Koushik Sen for PLDI08 Postponed = { }

40 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1(); s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); (s5,s6) in race Execution: s1: g1(); Slide taken and adapted from the original slides of Koushik Sen for PLDI08 Postponed = { }

41 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1(); s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); Execution: s1: g1(); (s5,s6) in race Slide taken and adapted from the original slides of Koushik Sen for PLDI08 Postponed = { }

42 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1() s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); Execution: s1: g1(); (s5,s6) in race Slide taken and adapted from the original slides of Koushik Sen for PLDI08 Postponed = { }

43 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1() s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); Execution: s1: g1(); (s5,s6) in race Slide taken and adapted from the original slides of Koushik Sen for PLDI08 Postponed = { }

44 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1() s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); (s5,s6) in race Execution: s1: g1(); s6: if (o1.f==1) Slide taken and adapted from the original slides of Koushik Sen for PLDI08 Postponed = { }

45 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1() s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); (s5,s6) in race Execution: s1: g1(); s6: if (o1.f==1) Slide taken and adapted from the original slides of Koushik Sen for PLDI08 Postponed = { }

46 Actual Data Race? 1: Inputs: the initial state s0, a set of two racing statements RaceSet 2: s := s0 3: postponed := ∅ 4: while Enabled(s) != ∅ do 5: t := a random thread in Enabled(s) \ postponed 6: if NextStmt(s, t) ∈ RaceSet then 7: R := Racing (s, t, postponed) 8: if R != ∅ then /* Actual race detected */ 9: print “ERROR: actual race found” 10: /* Randomly resolve race */ 11: if random boolean then 12: s := Execute(s, t) 13: else 14: postponed := postponed ∪ {t } 15: for all t‘ ∈ R do 16: s := Execute(s, t‘) 17: postponed := postponed \{t’} 18: end for 19: end if 20: else /* Wait for a race to happen */ 21: postponed := postponed ∪ {t} 22: end if 23: else 24: s := Execute(s, t) 25: end if 26: if postponed = Enabled(s) then 27: remove a random element from postponed 28: end if 29: end while 30: if Active(s) != ∅ then 31: print “ERROR: actual deadlock found” 32: end if

47 Actual Data Race? 7: R := Racing (s, t, postponed) 8: if R != ∅ then /* Actual race*/ … 20: else /* Wait for a race*/ 21: postponed := postponed ∪ {t} 22: end if

48 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1() s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); Execution: s1: g1(); s6: if (o1.f==1) (s5,s6) in race Postponed = { } Slide taken and adapted from the original slides of Koushik Sen for PLDI08

49 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1() s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); (s5,s6) in race Execution: s1: g1(); s6: if (o1.f==1) Postponed = { s6: if (o1.f==1) } Slide taken and adapted from the original slides of Koushik Sen for PLDI08

50 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1() s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); Execution: s1: g1(); (s5,s6) in race Postponed = { s6: if (o1.f==1) } Slide taken and adapted from the original slides of Koushik Sen for PLDI08

51 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1() s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); Execution: s1: g1(); s2: g2(); (s5,s6) in race Postponed = { s6: if (o1.f==1) } Slide taken and adapted from the original slides of Koushik Sen for PLDI08

52 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1() s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); Execution: s1: g1(); s2: g2(); (s5,s6) in race Postponed = { s6: if (o1.f==1) } Slide taken and adapted from the original slides of Koushik Sen for PLDI08

53 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1() s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); Execution: s1: g1(); s2: g2(); (s5,s6) in race Postponed = { s6: if (o1.f==1) } Slide taken and adapted from the original slides of Koushik Sen for PLDI08

54 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1() s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); (s5,s6) in race Postponed = { s6: if (o1.f==1) } Execution: s1: g1(); s2: g2(); s3: g3(); Slide taken and adapted from the original slides of Koushik Sen for PLDI08

55 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1() s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); (s5,s6) in race Postponed = { s6: if (o1.f==1) } Execution: s1: g1(); s2: g2(); s3: g3(); Slide taken and adapted from the original slides of Koushik Sen for PLDI08

56 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1() s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); (s5,s6) in race Postponed = { s6: if (o1.f==1) } Execution: s1: g1(); s2: g2(); s3: g3(); s4: g4(); Slide taken and adapted from the original slides of Koushik Sen for PLDI08

57 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1() s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); (s5,s6) in race Postponed = { s6: if (o1.f==1) } Execution: s1: g1(); s2: g2(); s3: g3(); s4: g4(); s5: o2.f = 1; Slide taken and adapted from the original slides of Koushik Sen for PLDI08

58 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1() s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); (s5,s6) in race Execution: s1: g1(); s2: g2(); s3: g3(); s4: g4(); s5: o2.f = 1; Slide taken and adapted from the original slides of Koushik Sen for PLDI08 Postponed = { s6: if (o1.f==1) }

59 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1() s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); (s5,s6) in race Race? Execution: s1: g1(); s2: g2(); s3: g3(); s4: g4(); s5: o2.f = 1; Slide taken and adapted from the original slides of Koushik Sen for PLDI08 Postponed = { s6: if (o1.f==1) }

60 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1() s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); (s5,s6) in race Postponed = { s6: if (o1.f==1) } Race? NO o1.f ≠ o2.f Execution: s1: g1(); s2: g2(); s3: g3(); s4: g4(); s5: o2.f = 1; Slide taken and adapted from the original slides of Koushik Sen for PLDI08

61 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1() s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); (s5,s6) in race Execution: s1: g1(); s2: g2(); s3: g3(); s4: g4(); s5: o2.f = 1; Slide taken and adapted from the original slides of Koushik Sen for PLDI08 Postponed = { s6: if (o1.f==1), s5: o2.f = 1; }

62 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1() s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); (s5,s6) in race Postponed = { s6: if (o1.f==1), s5: o2.f = 1; } Execution: s1: g1(); s2: g2(); s3: g3(); s4: g4(); Slide taken and adapted from the original slides of Koushik Sen for PLDI08

63 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1() s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); (s5,s6) in race Postponed = { s6: if (o1.f==1), s5: o2.f = 1; } Execution: s1: g1(); s2: g2(); s3: g3(); s4: g4(); Slide taken and adapted from the original slides of Koushik Sen for PLDI08

64 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1() s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); Execution: s1: g1(); s2: g2(); s3: g3(); s4: g4(); s5: o1.f = 1; (s5,s6) in race Postponed = { s6: if (o1.f==1), s5: o2.f = 1; } Slide taken and adapted from the original slides of Koushik Sen for PLDI08

65 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1() s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); Execution: s1: g1(); s2: g2(); s3: g3(); s4: g4(); s5: o1.f = 1; (s5,s6) in race Postponed = { s6: if (o1.f==1), s5: o2.f = 1; } Slide taken and adapted from the original slides of Koushik Sen for PLDI08

66 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1() s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); (s5,s6) in race Postponed = { s6: if (o1.f==1), s5: o2.f = 1; } Race? YES o1.f = o1.f Execution: s1: g1(); s2: g2(); s3: g3(); s4: g4(); s5: o1.f = 1; Slide taken and adapted from the original slides of Koushik Sen for PLDI08

67 Actual Data Race! 1: Inputs: the initial state s0, a set of two racing statements RaceSet 2: s := s0 3: postponed := ∅ 4: while Enabled(s) != ∅ do 5: t := a random thread in Enabled(s) \ postponed 6: if NextStmt(s, t) ∈ RaceSet then 7: R := Racing (s, t, postponed) 8: if R != ∅ then /* Actual race detected */ 9: print “ERROR: actual race found” 10: /* Randomly resolve race */ 11: if random boolean then 12: s := Execute(s, t) 13: else 14: postponed := postponed ∪ {t } 15: for all t‘ ∈ R do 16: s := Execute(s, t‘) 17: postponed := postponed \{t’} 18: end for 19: end if 20: else /* Wait for a race to happen */ 21: postponed := postponed ∪ {t} 22: end if 23: else 24: s := Execute(s, t) 25: end if 26: if postponed = Enabled(s) then 27: remove a random element from postponed 28: end if 29: end while 30: if Active(s) != ∅ then 31: print “ERROR: actual deadlock found” 32: end if

68 Actual Data Race! 9: print “ERROR: actual race found” 10: /* Randomly resolve race */ 11: if random boolean then 12: s := Execute(s, t) 13: else 14: postponed := postponed ∪ {t } 15: for all t‘ ∈ R do 16: s := Execute(s, t‘) 17: postponed := postponed \{t’} 18: end for 19: end if

69 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1() s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); (s5,s6) in race Postponed = { s6: if (o1.f==1), s5: o2.f = 1; } Race? YES o1.f = o1.f Execution: s1: g1(); s2: g2(); s3: g3(); s4: g4(); s5: o1.f = 1; Slide taken and adapted from the original slides of Koushik Sen for PLDI08

70 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1() s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); Execution: s1: g1(); s2: g2(); s3: g3(); s4: g4(); (s5,s6) in race Postponed = { s5: o2.f = 1; } s6: if (o1.f==1) s5: o1.f = 1; Slide taken and adapted from the original slides of Koushik Sen for PLDI08

71 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1() s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); Execution: s1: g1(); s2: g2(); s3: g3(); s4: g4(); s5: o1.f = 1; (s5,s6) in race Slide taken and adapted from the original slides of Koushik Sen for PLDI08 Postponed = { s6: if (o1.f==1), s5: o2.f = 1; }

72 Everybody Is Postponed? 1: Inputs: the initial state s0, a set of two racing statements RaceSet 2: s := s0 3: postponed := ∅ 4: while Enabled(s) != ∅ do 5: t := a random thread in Enabled(s) \ postponed 6: if NextStmt(s, t) ∈ RaceSet then 7: R := Racing (s, t, postponed) 8: if R != ∅ then /* Actual race detected */ 9: print “ERROR: actual race found” 10: /* Randomly resolve race */ 11: if random boolean then 12: s := Execute(s, t) 13: else 14: postponed := postponed ∪ {t } 15: for all t‘ ∈ R do 16: s := Execute(s, t‘) 17: postponed := postponed \{t’} 18: end for 19: end if 20: else /* Wait for a race to happen */ 21: postponed := postponed ∪ {t} 22: end if 23: else 24: s := Execute(s, t) 25: end if 26: if postponed = Enabled(s) then 27: remove a random element from postponed 28: end if 29: end while 30: if Active(s) != ∅ then 31: print “ERROR: actual deadlock found” 32: end if

73 Everybody Is Postponed? 26: if postponed = Enabled(s) then 27: remove a random element from postponed 28: end if

74 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1() s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); Execution: s1: g1(); s2: g2(); s3: g3(); s4: g4(); s5: o1.f = 1; (s5,s6) in race Slide taken and adapted from the original slides of Koushik Sen for PLDI08 Postponed = { s6: if (o1.f==1), s5: o2.f = 1; }

75 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1() s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); Execution: s1: g1(); s2: g2(); s3: g3(); s4: g4(); s5: o1.f = 1; s6: if (o1.f==1) (s5,s6) in race Postponed = { s5: o2.f = 1; } Slide taken and adapted from the original slides of Koushik Sen for PLDI08

76 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1() s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); Execution: s1: g1(); s2: g2(); s3: g3(); s4: g4(); s5: o1.f = 1; s6: if (o1.f==1) s7: ERROR; (s5,s6) in race Postponed = { s5: o2.f = 1; } Slide taken and adapted from the original slides of Koushik Sen for PLDI08

77 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1() s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); Execution: s1: g1(); s2: g2(); s3: g3(); s4: g4(); s5: o1.f = 1; s6: if (o1.f==1) s7: ERROR; s5: o2.f = 1; (s5,s6) in race Postponed = { } Slide taken and adapted from the original slides of Koushik Sen for PLDI08

78 Deadlock? 1: Inputs: the initial state s0, a set of two racing statements RaceSet 2: s := s0 3: postponed := ∅ 4: while Enabled(s) != ∅ do 5: t := a random thread in Enabled(s) \ postponed 6: if NextStmt(s, t) ∈ RaceSet then 7: R := Racing (s, t, postponed) 8: if R != ∅ then /* Actual race detected */ 9: print “ERROR: actual race found” 10: /* Randomly resolve race */ 11: if random boolean then 12: s := Execute(s, t) 13: else 14: postponed := postponed ∪ {t } 15: for all t‘ ∈ R do 16: s := Execute(s, t‘) 17: postponed := postponed \{t’} 18: end for 19: end if 20: else /* Wait for a race to happen */ 21: postponed := postponed ∪ {t} 22: end if 23: else 24: s := Execute(s, t) 25: end if 26: if postponed = Enabled(s) then 27: remove a random element from postponed 28: end if 29: end while 30: if Active(s) != ∅ then 31: print “ERROR: actual deadlock found” 32: end if

79 Deadlock? 30: if Active(s) != ∅ then 31: print “ERROR: actual deadlock found” 32: end if

80 RACEFUZZER using an example Thread1 foo(o1); foo(C x) { s1: g1() s2: g2(); s3: g3(); s4: g4(); s5: x.f = 1; } Thread2 bar(o1); bar(C y) { s6: if (y.f==1) s7: ERROR; } Thread3 foo(o2); Execution: s1: g1(); s2: g2(); s3: g3(); s4: g4(); s5: o1.f = 1; s6: if (o1.f==1) s7: ERROR; s5: o2.f = 1; (s5,s6) in race Postponed = { } Slide taken and adapted from the original slides of Koushik Sen for PLDI08

81 Deterministic Replay There are 3 points of non-determinism in the algorithm: Both are because of calls to a random function. If we save the random function seed before we start running RaceFuzzer, we can later replay the same run over and over using the same seed. 5: t := a random thread in Enabled(s) \ postponed 11: if random boolean then 27: remove a random element from postponed

82 Evaluation

83 RaceFuzzer Limitations  Cannot detect all real races in a concurrent program.  Depends on the dynamic analysis done in the first stage.  Being random in nature, RaceFuzzer may not be able to separate all real races from potential races.  However, this did not happen in our experiments with existing benchmarks.

84 Conclusion  RaceFuzzer  Classifies real Data Races  Enables reproduction of races found  No false positives!  Very efficient  Finds some exceptions and Deadlocks as a bonus. 84

85 QUESTIONS? 85

86 False Positive? Thread1 foo(x,y); foo(int x, int y) { s1: x = 1; s2: lock(L); s3: y = 1; s4: unlock(L); } Thread2 bar(x,y); bar(int x, int y) { s6: lock(L); s7: if (y == 1) { s8: if (x != 1) { s9: do something; }} s10: unlock(L); } Slide taken and adapted from the original slides of Koushik Sen for PLDI08 (s1,s8) in race Postponed = { s1: x = 1; } Execution: s6: lock(L); s7: if (y == 1) { s8: if (x != 1) { s9: do something; }} s10: unlock(L); s1: x = 1; s2: lock(L); s3: y = 1; s4: unlock(L); Postponed = {}

87 Hard To Find Data Races? Thread1 foo(x,y); foo(int x) { s1: for (i=0; i<1,000,000; ++i); s2: x = x+1; } Thread2 bar(x,y); bar(int x) { s3: x = x+1; } (s2,s3) in race Postponed = { s3: x = x+1; } Execution: s1: for (i=0; i<1,000,000; ++i); s2: x = x+1;s3: x = x+1; Data Race


Download ppt "Race Directed Random Testing of Concurrent Programs KOUSHIK SEN - UNIVERSITY OF CALIFORNIA, BERKELEY PRESENTED BY – ARTHUR KIYANOVSKI – TECHNION, ISRAEL."

Similar presentations


Ads by Google