Top Banner
Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking
46

Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Dec 16, 2015

Download

Documents

Giles Ellis
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Madan Musuvathi

Joint work with

Sebastian Burckhardt, Chris Dern, Roy Tan

LineUp:Automatic Thread Safety Checking

Page 2: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

MotivationConcurrent applications are common place

Correct synchronization is tricky

Modular programming with “thread-safe” componentsHide synchronization details within each componentExpose a simpler sequential interfaceCan be called concurrently without additional

synchronization

Page 3: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Example of a Thread-Safe Component

Component = state + set of operations

Clients can concurrently call these operations without additional synchronization

Concurrent Queue still behaves like a “queue”

Concurrent Queue

State = List of elements

push(…)

pop(…)

Page 4: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

In this talk

A precise formalization of thread safetyDeterministic Linearizability

An automatic method for checking thread safety

Page 5: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Let’s Write a Test

q = new ConcurrentQueue();

q.push(10); t = q.pop();

Assert( ? )

Page 6: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Let’s Write a Test

q = new ConcurrentQueue();

q.push(10); t = q.pop();

Assert:q.size() is 0 or 1

Page 7: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Let’s Write a Test

q = new ConcurrentQueue();

q.push(10); t = q.pop();

Assert:q.size() is 0 or 1

and t is 10 or <fail>

Page 8: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Let’s Write a Test

q = new ConcurrentQueue();

q.push(10); t = q.pop();

Assert: t = fail && q.size() = 1 &&

q.peek() == 10 || t = 10 && q.size() = 0

Page 9: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Let’s Write a Test

q = new ConcurrentQueue();

q.push(10);t = q.pop();

q.push(20);u = q.pop();

Assert ( ? )

Page 10: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Let’s Write a Test

q = new ConcurrentQueue();

q.push(10);t = q.pop();

q.push(20);u = q.pop();

Assert:q.size() == 0 &&

t = 10 || t = 20 &&u = 10 || t = 20 &&

u != t

Page 11: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Let’s Write a Test

q = new ConcurrentQueue();

q.push(10);t1 = q.pop();t2 = q.peek();q.push(20);

Assert ( ? )

q.push(30);u1 = q.peek();q.push(40);u2 = q.pop();

v1 = q.pop();q.push(50);v2 = q.peek();q.push(60);

Page 12: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

We want to simply say…

q = new ConcurrentQueue();

q.push(10);t1 = q.pop();t2 = q.peek();q.push(20);

Assert:

ConcurrentQueue behaves

like a queue

q.push(30);u1 = q.peek();q.push(40);u2 = q.pop();

v1 = q.pop();q.push(50);v2 = q.peek();q.push(60);

Page 13: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Linearizability [Herlihy & Wing ‘90]

ConcurrentQueue behaves like a queue

Concurrent behaviors of

ConcurrentQueue

are consistent

with

a sequential specification of a queue

Page 14: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Sequential Specification of a QueueA concise way to specify the behavior when

operations are performed one at a time

And so on …

[]

[10]push(10)

pop() -> <fail> [9]push(9)

pop() -> 10

pop() -> 9

[10, 9]push(9)

[9, 10]push(10)

Page 15: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Linearizability [Herlihy & Wing ‘90]

ConcurrentQueue behaves like a queue

Concurrent behaviors of

ConcurrentQueue

are consistent

with

a sequential specification of a queue

Every operation appears to occur atomically at some point between the

call and return

Page 16: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

LinearizabilityComponent is linearizable if every operation

appears to occur atomically at some point between the call and return

Thread 1

Thread 2

Thread 3

push 10 return push 20 return

pop return10

pop return “empty”

Page 17: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

A Linearizability ViolationHistory shown below is not linearizable

Thread 1push 20 return pop return 20

Thread 2push 10 return pop return empty

Page 18: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Solution using Linearizability

q = new ConcurrentQueue();

q.push(10);t1 = q.pop();t2 = q.peek();q.push(20);

Assert: Every concurrent behavior

(for this test) is linearizable

q.push(30);u1 = q.peek();q.push(40);u2 = q.pop();

v1 = q.pop();q.push(50);v2 = q.peek();q.push(60);

Page 19: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Providing Sequential Specification is HardComplexity:

API for java.util.concurrent.BlockingQueue<T> contains 28 functions

Logic:Even simple specifications require sophisticated logicsNeed to make the accessible to programmers

InsightWe have the code for the componentLearn the specification automatically

Page 20: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Deterministic Linearizability

ConcurrentQueue behaves like a queue

Concurrent behaviors of

ConcurrentQueue

are consistent

with

a sequential specification of a queue

Some determinstic sequential

specification of a queue

Learn this by observing the code under sequential runs

Page 21: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

The LineUp PropositionBe complete

all reported violations are conclusive refutations

Be automaticUser specifies component interface (gives list of operation

calls), tool does the rest

Be reasonably soundquantify unsoundness sources (missed bugs)Demonstrate empirically that we find enough real bugs

Page 22: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Implementation (part 1: generate Unit Tests)

RandomTestcase

GeneratorCollection of

Tests

Thread 1 Thread 2 Thread 3q.Add(10)q.Add(20)

q.TryTake() q.TryTake()q.Add(10),q.Add(20),q.TryTake(),q.Clear()

specifyoperations,# tests,size of tests

Example of a concurrent unit test:Example: queueoperations

Page 23: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

complete successfully

Implementation (part 2: check Each TEst)

Thread 1 Thread 2 Thread 3

q.Add(10)q.Remove()q.Clear()

q.Remove()q.Clear()q.Add(10)

q.Remove()q.Remove()q.Add(20)

unit test

reportviolating

execution

componentunder test(bytecode)

2-Phase Check

Page 24: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

THE Two-Phase check (Phase 1)

Enumerate Serial Historiesrecord all observations (incl.

return values) in filewe are synthesizing a

sequential specification!

Unit TestCHESSstateless model checker

Thread 1 Thread 2

Add(200)TryTake()

Add(400)TryTake()

Queue Implementation(Bytecode)

200

400

200

400

400

200

400

200

200

400

200

400

PHASE 1

Page 25: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

THE Two-Phase check (Phase 2)

Enumerate Concurrent Historiescheck against specificationreport violations

Unit Test CHESSstateless model checker

# of fair executions is finite! [PLDI 07]

Thread 1 Thread 2

Add(200)TryTake()

Add(400)TryTake()

200

200

200

400

200

400

400

200

400

200

200

400

200

400

PHASE 2

check

Queue Implementation(Bytecode)

Page 26: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

The Two-Phase Check: theoremsCompleteness

A counterexample refutes deterministic linearizability (i.e. proves that no deterministic sequential specification exists).

Restricted SoundnessIf the component is not deterministically linearizable, there

exists a unit test that fails.

How sound in practice?E.g. how good are 100 random 3x3 tests?

Page 27: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Results: Phase 1 / Phase 2

Page 28: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Results

Example: incorrect CASvolatile int state;

...int localstate = state;int newstate = f(state); // compute new valuecompare_and_swap(&state, localstate,

newstate);...

}

7 ClassicalConcurrencyBugs

Should use

localstate!

Page 29: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

ResultsCancel is not

linearizable(may delay past return)

Barrier is not linearizable(rendezvous not equivalent to any interleaved commit)

Page 30: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Resultsnondet.:

bag may return any element

nondet.:(weak spec) Count may return 0 and TryTake may return false even if not empty

Page 31: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Related Work / Other ApproachesTwo-Phase Check

CheckFence [PLDI 07], less automatic, only SCRace Detection

The bugs we found do not manifest as data racesAtomicity (Conflict-Serializability) Checking

Many false alarms (programmers are creative)Traditional Linearizability Verification

less automatic (proofs, specs, commit points)does not detect incorrect blocking

Page 32: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Extending Classic LinearizabilityWe check deadlocks more tightly.

[Herlihy, Moss]: Deadlocked histories are considered linearizable even if operations do not block in sequential specification.

[Line-Up]: Deadlocked histories qualify as linearizable only if sequential specification allows all pending operations to block.

Page 33: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

ConclusionSuccess:

Found tricky concurrency bugs in public production codeBugs were fixed

Deterministic linearizability is a useful thread-safety criterionCan be checked automaticallyIn our case, better than race detection or atomicity checking

High-value addition to CHESSDramatically automates the processCHESS source release now available!

Page 34: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Let’s Write a Test

q = new ConcurrentQueue();

q.push(10); t = q.pop();

Assert( ? )

Page 35: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Let’s Write a Test

q = new ConcurrentQueue();

q.push(10); t = q.pop();

Assert:q.size() is 0 or 1

Page 36: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Let’s Write a Test

q = new ConcurrentQueue();

q.push(10); t = q.pop();

Assert:q.size() is 0 or 1

and t is 10 or <fail>

Page 37: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Let’s Write a Test

q = new ConcurrentQueue();

q.push(10); t = q.pop();

Assert: t = fail && q.size() = 1 &&

q.peek() == 10 || t = 10 && q.size() = 0

Page 38: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Let’s Write a Test

q = new ConcurrentQueue();

q.push(10);t = q.pop();

q.push(20);u = q.pop();

Assert ( ? )

Page 39: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Let’s Write a Test

q = new ConcurrentQueue();

q.push(10);t = q.pop();

q.push(20);u = q.pop();

Assert:q.size() == 0 &&

t = 10 || t = 20 &&u = 10 || t = 20 &&

u != t

Page 40: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Let’s Write a Test

q = new ConcurrentQueue();

q.push(10);t1 = q.pop();t2 = q.peek();q.push(20);

Assert ( ? )

q.push(30);u1 = q.peek();q.push(40);u2 = q.pop();

v1 = q.pop();q.push(50);v2 = q.peek();q.push(60);

Page 41: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Wouldn’t it be nice if we could just say…

q = new ConcurrentQueue();

q.push(10);t1 = q.pop();t2 = q.peek();q.push(20);

Assert:

ConcurrentQueue behaves

like a queue

q.push(30);u1 = q.peek();q.push(40);u2 = q.pop();

v1 = q.pop();q.push(50);v2 = q.peek();q.push(60);

Page 42: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Informally, this is “thread safety”

ConcurrentQueue behaves like a queue

A piece of code is thread-safe if it functions correctly during simultaneous

execution by multiple threads.

Page 43: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Formally, this is “Linearizability” [Herlihy & Wing ‘90]

ConcurrentQueue behaves like a queue

Concurrent behaviors of

ConcurrentQueue

are consistent

with

a sequential specification of a queue

Every operation appears to occur atomically at some point between the

call and return

Page 44: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

So, simply check linearizability

q = new ConcurrentQueue();

q.push(10);t1 = q.pop();t2 = q.peek();q.push(20);

Assert:

Linearizability wrt a given sequential

specification

q.push(30);u1 = q.peek();q.push(40);u2 = q.pop();

v1 = q.pop();q.push(50);v2 = q.peek();q.push(60);

Page 45: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

Automatic Thread Safety Checking

q = new ConcurrentQueue();

q.push(10);t1 = q.pop();t2 = q.peek();q.push(20);

Assert:

ConcurrentQueue is Thread Safe

q.push(30);u1 = q.peek();q.push(40);u2 = q.pop();

v1 = q.pop();q.push(50);v2 = q.peek();q.push(60);

Automatically learn how “a queue” behaves

Page 46: Madan Musuvathi Joint work with Sebastian Burckhardt, Chris Dern, Roy Tan LineUp: Automatic Thread Safety Checking.

ConclusionsBeware of race conditions when you are designing

your programsThink of all source of nondeterminismReason about the space of program behaviors

Use tools to explore the spaceCuzz: Randomized algorithm for large programsCHESS: systematic algorithm for unit testingThread-safety as a correctness criterion