Upload
yoshi-fuller
View
42
Download
2
Tags:
Embed Size (px)
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
Citation preview
C. Flanagan SAS’04: Type Inference Against Races 1
Type Inference Against Races
Cormac FlanaganUC Santa Cruz
Stephen N. FreundWilliams College
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!
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; }}
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;
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
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
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, ...
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;
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 }
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
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
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
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;
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
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
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
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
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
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
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;
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
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
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
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
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
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}
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)
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;
}
}
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;
}
}
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
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
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
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
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]
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,
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 }
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 }
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 }
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 }
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)
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
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
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, ...
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
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
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!
C. Flanagan SAS’04: Type Inference Against Races 47
Type Inference Against Races
Cormac FlanaganUC Santa Cruz
Stephen N. FreundWilliams College