Type Inference Against Races

47
C. Flanagan SAS’04: Type Inference Against Races 1 Type Inference Against Races Cormac Flanagan UC Santa Cruz Stephen N. Freund Williams College

description

Type Inference Against Races. Cormac Flanagan UC Santa Cruz. Stephen N. Freund Williams College. Software Validation & Verification. Standard approach: Testing test coverage problem Multithreaded software increasing widespread (Java, C#, GUIs, servers) testing inadequate due to - PowerPoint PPT Presentation

Transcript of Type Inference Against Races

Page 1: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 1

Type Inference Against Races

Cormac FlanaganUC Santa Cruz

Stephen N. FreundWilliams College

Page 2: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 2

Software Validation & Verification

• Standard approach: Testing– test coverage problem

• Multithreaded software– increasing widespread (Java, C#, GUIs, servers)– testing inadequate due to

• test coverage• scheduling coverage

• An important application for static analysis!

Page 3: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 3

Errors in Multithreaded Software

class Ref { int i; void add(Ref r) { i = i + r.i; }}

Page 4: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 4

Errors in Multithreaded Software

class Ref { int i; void add(Ref r) { i = i + r.i; }} Ref x = new Ref(0);Ref y = new Ref(3);

x.add(y); x.add(y);

assert x.i == 6;

Page 5: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 5

Errors in Multithreaded Software

class Ref { int i; void add(Ref r) { i = i + r.i; }} Ref x = new Ref(0);Ref y = new Ref(3);parallel { x.add(y); // two calls happen x.add(y); // in parallel}assert x.i == 6;

A race condition occurs if

• two threads access a shared variable at the same time

• at least one of those accesses is a write

Page 6: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 6

Lock-Based Synchronization

class Ref { int i; // guarded by this void add(Ref r) { i = i + r.i; }} Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (x,y) { x.add(y); } synchronized (x,y) { x.add(y); }}assert x.i == 6;

• Field guarded by a lock

• Lock acquired before accessing field

• Ensures race freedom

Page 7: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 7

Verifying Race Freedom

• Race freedom a key correctness property

• Rccjava [Flanagan-Freund, PLDI’99]– race condition checker for Java– verifies race freedom using a static analysis– analysis expressed as a type system– type annotations to specify locking discipline

• guarded_by, requires, ...

Page 8: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 8

Verifying Race Freedom with Types

class Ref { int i; void add(Ref r) { i = i + r.i; }} Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (x,y) { x.add(y); } synchronized (x,y) { x.add(y); }}assert x.i == 6;

Page 9: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 9

Verifying Race Freedom with Types

class Ref { int i guarded_by this; void add(Ref r) requires this, r { i = i + r.i; }} Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (x,y) { x.add(y); } synchronized (x,y) { x.add(y); }}assert x.i == 6;

check: this { this, r }

Page 10: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 10

Verifying Race Freedom with Types

class Ref { int i guarded_by this; void add(Ref r) requires this, r { i = i + r.i; }} Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (x,y) { x.add(y); } synchronized (x,y) { x.add(y); }}assert x.i == 6;

check: this { this, r } check: this[this:=r] = r { this, r }

replace this by r

Page 11: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 11

Verifying Race Freedom with Types

class Ref { int i guarded_by this; void add(Ref r) requires this, r { i = i + r.i; }} Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (x,y) { x.add(y); } synchronized (x,y) { x.add(y); }}assert x.i == 6;

check: this { this, r } check: this[this:=r] = r { this, r }

check: {this,r}[this:=x,r:=y] { x, y }

replace formals this,rby actuals x,y

Page 12: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 12

Verifying Race Freedom with Types

class Ref { int i guarded_by this; void add(Ref r) requires this, r { i = i + r.i; }} Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (x,y) { x.add(y); } synchronized (x,y) { x.add(y); }}assert x.i == 6;

check: {this,r}[this:=x,r:=y] { x, y }

check: this { this, r } check: this[this:=r] = r { this, r }

check: {this,r}[this:=x,r:=y] { x, y }

Soundness Theorem:Well-typed programs are race-free

replace formals this,rby actuals x,y

Page 13: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 13

Basic Type Inference

class Ref { int i; void add(Ref r) { i = i + r.i; }} Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (x,y) { x.add(y); } synchronized (x,y) { x.add(y); }}assert x.i == 6;

Page 14: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 14

Basic Type Inferencestatic final Object m =new Object();

class Ref { int i; void add(Ref r) { i = i + r.i; }} Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (x,y) { x.add(y); } synchronized (x,y) { x.add(y); }}assert x.i == 6;

Iterative GFP algorithm:• [Flanagan-Freund,

PASTE’01]

• Start with maximum set of annotations

Page 15: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 15

Basic Type Inferencestatic final Object m =new Object();

class Ref { int i guarded_by this, m; void add(Ref r) { i = i + r.i; }} Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (x,y) { x.add(y); } synchronized (x,y) { x.add(y); }}assert x.i == 6;

Iterative GFP algorithm:• [Flanagan-Freund,

PASTE’01]

• Start with maximum set of annotations

Page 16: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 16

Basic Type Inferencestatic final Object m =new Object();

class Ref { int i guarded_by this, m; void add(Ref r) requires this, r, m { i = i + r.i; }} Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (x,y) { x.add(y); } synchronized (x,y) { x.add(y); }}assert x.i == 6;

Iterative GFP algorithm:• [Flanagan-Freund,

PASTE’01]

• Start with maximum set of annotations

Page 17: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 17

Basic Type Inferencestatic final Object m =new Object();

class Ref { int i guarded_by this, m; void add(Ref r) requires this, r, m { i = i + r.i; }} Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (x,y) { x.add(y); } synchronized (x,y) { x.add(y); }}assert x.i == 6;

XX

Iterative GFP algorithm:• [Flanagan-Freund,

PASTE’01]

• Start with maximum set of annotations

• Iteratively remove all incorrect annotations

Page 18: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 18

Basic Type Inferencestatic final Object m =new Object();

class Ref { int i guarded_by this, m; void add(Ref r) requires this, r, m { i = i + r.i; }} Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (x,y) { x.add(y); } synchronized (x,y) { x.add(y); }}assert x.i == 6;

XX

Iterative GFP algorithm:• [Flanagan-Freund, PASTE’01]

• Start with maximum set of annotations

• Iteratively remove all incorrect annotations

• Check each field still has a protecting lock

Sound, complete, fast

But type system too basic

Page 19: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 19

Harder Example: External Locking

class Ref { int i; void add(Ref r) { i = i + r.i; }} Object m = new Object();Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (m) { x.add(y); } synchronized (m) { x.add(y); }}assert x.i == 6;

• Field i of x and y protected by external lock m

• Not typable with basic type system– m not in scope at i

• Requires more expressive type system with ghost parameters

Page 20: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 20

Ghost Parameters on Classes

class Ref { int i; void add(Ref r) { i = i + r.i; }} Object m = new Object();Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (m) { x.add(y); } synchronized (m) { x.add(y); }}assert x.i == 6;

Page 21: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 21

Ghost Parameters on Classes

class Ref<ghost g> { int i; void add(Ref r) { i = i + r.i; }} Object m = new Object();Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (m) { x.add(y); } synchronized (m) { x.add(y); }}assert x.i == 6;

• Ref parameterized by external ghost lock g

Page 22: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 22

Ghost Parameters on Classes

class Ref<ghost g> { int i guarded_by g; void add(Ref r) { i = i + r.i; }} Object m = new Object();Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (m) { x.add(y); } synchronized (m) { x.add(y); }}assert x.i == 6;

• Ref parameterized by external ghost lock g

• Field i guarded by g

Page 23: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 23

Ghost Parameters on Classes

class Ref<ghost g> { int i guarded_by g; void add(Ref r) requires g { i = i + r.i; }} Object m = new Object();Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (m) { x.add(y); } synchronized (m) { x.add(y); }}assert x.i == 6;

• Ref parameterized by external ghost lock g

• Field i guarded by g• g held when add

called

Page 24: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 24

Ghost Parameters on Classes

class Ref<ghost g> { int i guarded_by g; void add(Ref<g> r) requires g { i = i + r.i; }} Object m = new Object();Ref x = new Ref(0);Ref y = new Ref(3);parallel { synchronized (m) { x.add(y); } synchronized (m) { x.add(y); }}assert x.i == 6;

• Ref parameterized by external ghost lock g

• Field i guarded by g• g held when add

called• Argument r also

parameterized by g

Page 25: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 25

Ghost Parameters on Classes

class Ref<ghost g> { int i guarded_by g; void add(Ref<g> r) requires g { i = i + r.i; }} Object m = new Object();Ref<m> x = new Ref<m>(0);Ref<m> y = new Ref<m>(3);parallel { synchronized (m) { x.add(y); } synchronized (m) { x.add(y); }}assert x.i == 6;

• Ref parameterized by external ghost lock g

• Field i guarded by g• g held when add

called• Argument r also

parameterized by g

• x and y parameterized by lock m

Page 26: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 26

Type Checking Ghost Parameters

class Ref<ghost g> { int i guarded_by g; void add(Ref<g> r) requires g { i = i + r.i; }} Object m = new Object();Ref<m> x = new Ref<m>(0);Ref<m> y = new Ref<m>(3);parallel { synchronized (m) { x.add(y); } synchronized (m) { x.add(y); }}assert x.i == 6;

check: {g} [this:=x,r:=y, g:=m] {m}

Page 27: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 27

Type Inference with Ghosts• HARD

– iterative GFP algorithm does not work– check may fail because of two annotations

• which should we remove?

– requires backtracking search

• NP-complete!

• Our approach– reduce type inference to SAT– use fast, modern SAT solver (Chaff)

Page 28: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 28

Reducing Type Inference to SAT

class Ref {

int i;

void add(Ref r)

{

i = i

+ r.i;

}

}

Page 29: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 29

Reducing Type Inference to SAT

class Ref<ghost g1,g2,...,gn> {

int i;

void add(Ref r)

{

i = i

+ r.i;

}

}

Page 30: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 30

Reducing Type Inference to SAT

class Ref<ghost g> {

int i;

void add(Ref r)

{

i = i

+ r.i;

}

}

• Add ghost parameters <ghost g> to each class declaration

Page 31: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 31

Reducing Type Inference to SAT

class Ref<ghost g> {

int i guarded_by 1;

void add(Ref r)

{

i = i

+ r.i;

}

}

• Add ghost parameters <ghost g> to each class declaration

• Add guarded_by i to each field declaration– type inference resolves

i to some lock

Page 32: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 32

Reducing Type Inference to SAT

class Ref<ghost g> {

int i guarded_by 1;

void add(Ref<2> r)

{

i = i

+ r.i;

}

}

• Add ghost parameters <ghost g> to each class declaration

• Add guarded_by i to each field declaration– type inference resolves

i to some lock

• Add <2> to each class reference

Page 33: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 33

Reducing Type Inference to SAT

class Ref<ghost g> {

int i guarded_by 1;

void add(Ref<2> r)

requires {

i = i

+ r.i;

}

}

• Add ghost parameters <ghost g> to each class declaration

• Add guarded_by i to each field declaration– type inference resolves

i to some lock

• Add <2> to each class reference

• Add requires i to each method– type inference resolves

i to some set of locks

Page 34: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 34

Reducing Type Inference to SAT

class Ref<ghost g> {

int i guarded_by 1;

void add(Ref<2> r)

requires {

i = i

+ r.i;

}

}

Constraints:1 { this, g }

2 { this, g }

{ this, g, r }

1 1[this := r, g:= 2]

Page 35: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 35

Constraints:1 { this, g }

2 { this, g }

{ this, g, r }

1 1[this := r, g:= 2]

Reducing Type Inference to SAT

Encoding:

1 = (b1 ? this : g )

2 = (b2 ? this : g )

= { b3 ? this, b4 ? g, b5 ?

r }

class Ref<ghost g> {

int i guarded_by 1;

void add(Ref<2> r)

requires {

i = i

+ r.i;

}

}

Use boolean variablesb1,...,b5 to encode choices for 1, 2,

Page 36: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 36

Constraints:1 { this, g }

2 { this, g }

{ this, g, r }

1 1[this := r, g:= 2]

Reducing Type Inference to SAT

class Ref<ghost g> {

int i guarded_by 1;

void add(Ref<2> r)

requires {

i = i

+ r.i;

}

}

1[this := r, g:= 2]

Use boolean variablesb1,...,b5 to encode choices for 1, 2,

Encoding:

1 = (b1 ? this : g )

2 = (b2 ? this : g )

= { b3 ? this, b4 ? g, b5 ?

r }

Page 37: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 37

Constraints:1 { this, g }

2 { this, g }

{ this, g, r }

1 1[this := r, g:= 2]

Reducing Type Inference to SAT

class Ref<ghost g> {

int i guarded_by 1;

void add(Ref<2> r)

requires {

i = i

+ r.i;

}

}

1[this := r, g:= 2]

(b1 ? this : g ) [this := r, g:= 2]

Use boolean variablesb1,...,b5 to encode choices for 1, 2,

Encoding:

1 = (b1 ? this : g )

2 = (b2 ? this : g )

= { b3 ? this, b4 ? g, b5 ?

r }

Page 38: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 38

Constraints:1 { this, g }

2 { this, g }

{ this, g, r }

1 1[this := r, g:= 2]

Reducing Type Inference to SAT

class Ref<ghost g> {

int i guarded_by 1;

void add(Ref<2> r)

requires {

i = i

+ r.i;

}

}

1[this := r, g:= 2]

(b1 ? this : g ) [this := r, g:= 2]

(b1 ? r : 2)

Use boolean variablesb1,...,b5 to encode choices for 1, 2,

Encoding:

1 = (b1 ? this : g )

2 = (b2 ? this : g )

= { b3 ? this, b4 ? g, b5 ?

r }

Page 39: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 39

Constraints:1 { this, g }

2 { this, g }

{ this, g, r }

1 1[this := r, g:= 2]

Reducing Type Inference to SAT

class Ref<ghost g> {

int i guarded_by 1;

void add(Ref<2> r)

requires {

i = i

+ r.i;

}

}

1[this := r, g:= 2]

(b1 ? this : g ) [this := r, g:= 2]

(b1 ? r : 2)

(b1 ? r : (b2 ? this : g )) { b3 ? this, b4 ? g, b5 ?

r }

Use boolean variablesb1,...,b5 to encode choices for 1, 2,

Encoding:

1 = (b1 ? this : g )

2 = (b2 ? this : g )

= { b3 ? this, b4 ? g, b5 ?

r }

Page 40: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 40

Constraints:1 { this, g }

2 { this, g }

{ this, g, r }

1 1[this := r, g:= 2]

Reducing Type Inference to SAT

class Ref<ghost g> {

int i guarded_by 1;

void add(Ref<2> r)

requires {

i = i

+ r.i;

}

}

1[this := r, g:= 2]

(b1 ? this : g ) [this := r, g:= 2]

(b1 ? r : 2)

(b1 ? r : (b2 ? this : g )) { b3 ? this, b4 ? g, b5 ?

r }

Use boolean variablesb1,...,b5 to encode choices for 1, 2,

Encoding:

1 = (b1 ? this : g )

2 = (b2 ? this : g )

= { b3 ? this, b4 ? g, b5 ?

r }

Clauses:

(b1 b5) (b1 b2 b3)(b1 b2 b4)

Page 41: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 41

Overview of Type Inference

SAT soln:

b1=false...

ConstraintSolution:1 = g

...

SAT problem:

(b1 b5) ...

Constraints:

1 { this, g }

...

Add Unknowns:class Ref<ghost g> { int i guarded_by 1 ; ...

Annotated Program:class Ref<ghost g> { int i guarded_by g; ...

Unannotated Program:class Ref { int i; ...

b1,... encodes choice for 1,...

ChaffSAT solver

Error: potential race on field i

unsatisfiable

satisfiable

Page 42: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 42

Improving Precision• Synchronization not necessary if

– only a single thread exists– object never escapes its creating thread– object has not yet escaped its creating thread– read-shared field

• read-only after it escapes its creating thread

– code is unreachable

• Fields guarded_by expressions, not just vars – must be a constant expression– bound on size

Page 43: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 43

Implementation

• Full Java programming language– inheritance, subtyping, interfaces– inner classes, static fields and methods

• Separate SAT problem for each field decl– to identify fields with potential race conditions

• Generate MAX-SAT optimization problem– minimize number+complexity of error messages

• Supports extra manual annotations• /*# no_warn */, /*# single_threaded */• more ghost parameters, extra lock expressions, ...

Page 44: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 44

Experimental Results

Program

Lines

of

code

Number

of Fields

Manual

Annotations

(per KLOC)

I nference

time

(s/KLOC)

% fields

race

free

elevator 529 23 0.0 9.5 100tsp 723 37 4.1 9.5 92sor 687 29 1.5 6.6 100raytracer 1,982 77 1.0 10.6 95moldyn 1,408 107 2.1 8.9 94montecarlo 3,674 110 0.3 5.6 100mtrt 11,315 181 0.5 12.3 98jbb 30,519 787 1.3 90.9 97

Page 45: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 45

Summary

• Type inference for rccjava is NP-complete– due to ghost parameters – requires backtracking search

• Reduce type inference to SAT– adequately fast up to 30,000 LOC– precise: 92-100% of fields verified race free

Page 46: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 46

Future Work• Atomicity

– a key semantic correctness property for multithreaded code

– a method is atomic if concurrent threads do not interfere with its behavior

– sequential reasoning is OK for atomic methods

• Developing type-based analysis for atomicity– leverages information about race conditions– early result: 85% of methods in jbb are atomic!

Page 47: Type Inference Against Races

C. Flanagan SAS’04: Type Inference Against Races 47

Type Inference Against Races

Cormac FlanaganUC Santa Cruz

Stephen N. FreundWilliams College