Tiddle: A Trace Description Language for Generating Concurrent - - PowerPoint PPT Presentation

tiddle
SMART_READER_LITE
LIVE PREVIEW

Tiddle: A Trace Description Language for Generating Concurrent - - PowerPoint PPT Presentation

Tiddle: A Trace Description Language for Generating Concurrent Benchmarks to Test Dynamic Analyses Caitlin Sadowski Jaeheon Yi July 20, 2009 University of California at Santa Cruz Monday, July 20, 2009 1 Some


slide-1
SLIDE 1

Tiddle:

A Trace Description Language for Generating Concurrent Benchmarks to Test Dynamic Analyses

Caitlin Sadowski Jaeheon Yi July 20, 2009 University of California at Santa Cruz

1 Monday, July 20, 2009

slide-2
SLIDE 2
  • Data race
  • Atomicity
  • Deterministic Parallelism
  • Deadlock

Some Dynamic Analyses for Concurrency

GoodLock Pulse

Agarwal06

Burnim09

Deadlock Fuzzer Atom Fuzzer Block- Based Commit- Node

Atomizer

Eraser

Happens Before

FastTrack

Goldilocks

DJIT+

Velodrome

SideTrack SingleTrack

Atomizer

Eraser

Happens Before

FastTrack

Goldilocks

DJIT+

Velodrome

SideTrack SingleTrack

2 Monday, July 20, 2009

slide-3
SLIDE 3

SideTrack

RoadRunner Instrumenter

Java bytecode

events

Instrumented bytecode

JVM

T1: begin_atomic T2: acquire(lock3) T2: read(x,5) T1: write(y,3) T1: end_atomic T2: release(lock3)

RoadRunner

Atomicity violations

3 Monday, July 20, 2009

slide-4
SLIDE 4

RoadRunner

... x = 3; ...

Thread 1

... preWrite(x) x = 3; postWrite(x) ...

Instrumented Thread 1

void preWrite(x){ ... } void postWrite(x){ ... }

MyTool.java

4 Monday, July 20, 2009

slide-5
SLIDE 5

Thread t1 = new Thread(){ void run(){ x = 1; }}; Thread t2 = new Thread(){ void run(){ x = 2; }}; static int x; public static void main(){ t1.start(); t2.start(); } write x write x

Thread 1 Thread 2

Happens-Before (HB) Race

5 Monday, July 20, 2009

slide-6
SLIDE 6

HB Race

sync m { } write x sync m { } sync m { } write x sync m { }

Thread 1 Thread 2

No HB Race

sync m { } write x sync m { } sync m { } write x sync m { }

Thread 1 Thread 2

6 Monday, July 20, 2009

slide-7
SLIDE 7
  • ad hoc
  • no guarantees
  • can be complex
  • difficult to maintain

HB Race

sync m { } write x yield() sync m { } sync m { } write x sync m { }

Thread 1 Thread 2

What about adding yields? ... So how do we write traces to test tools?

7 Monday, July 20, 2009

slide-8
SLIDE 8

Thinking up Test Cases

8 Monday, July 20, 2009

slide-9
SLIDE 9

Tiddle: a domain specific

language for describing traces

trace ::= op*

  • p ::= rd Tid Var (Val)

| wr Tid Var (Val) | acq Tid Lock | rel Tid Lock | fork Tid Tid | join Tid Tid | beg Tid Label | end Tid Label

Tid ::= Int Var ::= String Val ::= Int Label ::= String

9 Monday, July 20, 2009

slide-10
SLIDE 10

quick way of testing dynamic analysis

  • Race condition:
//Generated by Tiddle, UC Santa Cruz package feasibleTests; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; public class RaceCondition { static int x = 0; static CyclicBarrier cb = new CyclicBarrier(2); static CyclicBarrier cc = new CyclicBarrier(2); static int counter = 0; static int numThreads = 2; static public void await(CyclicBarrier c) throws BrokenBarrierException, InterruptedException { c.await(); } static int getCounter() { return counter++; } public static void main(String[] args) { final Thread t2 = new Thread() { public void run() { try { int _z = 0; await(cc); await(cb); await(cc); x = getCounter(); await(cb); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } }; final Thread t1 = new Thread() { public void run() { try { int _z = 0; await(cc); _z = x; await(cb); await(cc); await(cb); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } }; t1.start(); t2.start(); } }

acq 1 m wr 1 x rel 1 m wr 2 x

10 Monday, July 20, 2009

slide-11
SLIDE 11

public class SimpleRace { static int x = 0; static Object m = new Object(); static CyclicBarrier cb = new CyclicBarrier(2); static public void await(CyclicBarrier c) throws BrokenBarrierException, InterruptedException { c.await(); } public static void main(String[] args) { final Thread t1 = new Thread() { public void run() { ... } }; final Thread t2 = new Thread() { public void run() { ... } }; t1.start(); t2.start(); } } acq 1 m wr 1 x rel 1 m wr 2 x

11 Monday, July 20, 2009

slide-12
SLIDE 12

public void run() { try { synchronized(m) { await(cb); x = 1; await(cb); } await(cb); await(cb); } catch (...) { ... } } }; public void run() { try { await(cb); await(cb); await(cb); x = 0; await(cb); } catch (...) { ... } } }; acq 1 m wr 1 x rel 1 m wr 2 x

Thread 1 Thread 2

1 1 2 2 3 3 4 4

12 Monday, July 20, 2009

slide-13
SLIDE 13

Unit Testing for Dynamic Analysis

  • Easy to describe test case as a trace
  • Compile trace to multithreaded test
  • barriers for determinism
  • avoid boilerplate and complexity

13 Monday, July 20, 2009

slide-14
SLIDE 14
  • Data race
  • Atomicity
  • Deterministic Parallelism
  • Deadlock

Some Dynamic Analyses for Concurrency

GoodLock Pulse

Agarwal06

Burnim09

Deadlock Fuzzer Atom Fuzzer Block- Based Commit- Node

Atomizer

Eraser

Happens Before

FastTrack

Goldilocks

DJIT+

Velodrome

SideTrack SingleTrack

Atomizer

Eraser

Happens Before

FastTrack

Goldilocks

DJIT+

Velodrome

SideTrack SingleTrack

14 Monday, July 20, 2009

slide-15
SLIDE 15

The effect of an atomic code block can be considered in isolation from the rest of a running program.

  • enables sequential reasoning
  • atomicity violations often represent

synchronization errors

  • most methods are atomic

Atomicity

15 Monday, July 20, 2009

slide-16
SLIDE 16

Thread 2

synchronized(m){ newVar = 0; }

acquire(n) t1 = bal release(n) acquire(m) newVar = 0 release(m)

Thread 1 Thread 2

Thread 1

atomic{ synchronized(n){ tmp = bal; } synchronized(n){ bal = tmp + 1; } }

begin acquire(n) bal = t + 1 release(n) end

Serial Trace: Each atomic block executes contiguously

16 Monday, July 20, 2009

slide-17
SLIDE 17

Thread 2

synchronized(m){ newVar = 0; }

acquire(n) t1 = bal release(n) acquire(m) newVar = 0 release(m)

Thread 1 Thread 2

Thread 1

atomic{ synchronized(n){ tmp = bal; } synchronized(n){ bal = tmp + 1; } }

begin acquire(n) bal = t + 1 release(n) end

Atomicity = Serializability

17 Monday, July 20, 2009

slide-18
SLIDE 18

Thread 1

atomic{ synchronized(n){ tmp = bal; } synchronized(n){ bal = tmp + 1; } }

acquire(n) t1 = bal release(n)

Thread 2

synchronized(n){ bal = 0; }

acquire(n) bal = 0 release(n)

Thread 1 Thread 2

acquire(n) bal = t + 1 release(n) begin end

18 Monday, July 20, 2009

slide-19
SLIDE 19

acquire(n) bal = 0 release(n)

Thread 1 Thread 2

acquire(n) t1 = bal release(n) begin acquire(n) bal = t + 1 release(n) end

Thread 1

atomic{ synchronized(n){ tmp = bal; } synchronized(n){ bal = tmp + 1; } }

Thread 2

synchronized(n){ bal = 0; }

19 Monday, July 20, 2009

slide-20
SLIDE 20
  • HB Atomicity Violation:

beg 1 b wr 1 x wr 2 x rd 1 x end 1 b

//Generated by Tiddle, UC Santa Cruz package feasibleTests; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; public class AtomicityViolation { static int x = 0; static CyclicBarrier cb = new CyclicBarrier(2); static CyclicBarrier cc = new CyclicBarrier(2); static int counter = 0; static int numThreads = 2; static public void await(CyclicBarrier c) throws BrokenBarrierException, InterruptedException { c.await(); } static int getCounter() { return counter++; } static void b() throws BrokenBarrierException, InterruptedException { await(cb); await(cc); x = getCounter(); await(cb); await(cc); await(cb); await(cc); _z = x; await(cb); await(cc); } public static void main(String[] args) { final Thread t2 = new Thread() { public void run() { try { int _z = 0; await(cc); await(cb); await(cc); await(cb); await(cc); x = getCounter(); await(cb); await(cc); await(cb); await(cc); await(cb); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } }; final Thread t1 = new Thread() { public void run() { try { int _z = 0; await(cc); b(); await(cb); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } }; t1.start(); t2.start(); } }

quick way of testing dynamic analysis

20 Monday, July 20, 2009

slide-21
SLIDE 21
  • HB Atomicity Violation:

beg 1 b acq 1 m rel 1 m acq 2 m rel 2 m acq 1 m rel 1 m end 1 b

quick way of testing dynamic analysis

21 Monday, July 20, 2009

slide-22
SLIDE 22
  • Serial trace
  • Feasibly non-serializable

beg 1 b acq 1 m rel 1 m acq 1 m rel 1 m end 1 b acq 2 m rel 2 m

quick way of testing dynamic analysis

22 Monday, July 20, 2009

slide-23
SLIDE 23

Tiddle Compiler

Lexer (alex) Parser (happy)

rd 1 x wr 2 y rd 1 y class Foo { ... }

Translation to Java AST PrettyPrinters (HughesPJ) PrettyPrinters (HughesPJ) PrettyPrinters (HughesPJ)

23 Monday, July 20, 2009

slide-24
SLIDE 24

Equivalent Traces

  • Equivalent modulo happens-before
  • Different total orderings of same HB

partial ordering

  • Analyses should behave same way
  • Regression testing for analyses

24 Monday, July 20, 2009

slide-25
SLIDE 25

Make Tiddle Traces Fix Analysis Rules Develop Formal Proof Pass Traces? Lots of Tests? Proof Checks?

YES NO YES NO NO

Write Up Work

YES

25 Monday, July 20, 2009

slide-26
SLIDE 26

Next Steps

  • Support for other Java features
  • volatiles, wait/notify, etc.
  • Bug capture
  • Specification language

26 Monday, July 20, 2009

slide-27
SLIDE 27

Not a Panacea

  • Helps you with the known unknowns
  • This won’t help you find the bugs

you’re not expecting

  • Doesn’t help you with the unknown

unknowns

27 Monday, July 20, 2009

slide-28
SLIDE 28

Conclusion

  • Domain-specific language
  • describe bugs succinctly
  • Generate Java test cases
  • multithreaded, deterministic
  • Helps dynamic analysis development
  • 100+ Tiddle traces to date

28 Monday, July 20, 2009