Static Detection of Race Conditions in Erlang Maria Christakis National Technical University of...
-
Upload
grace-copeland -
Category
Documents
-
view
218 -
download
0
Transcript of Static Detection of Race Conditions in Erlang Maria Christakis National Technical University of...
Static Detection of Race Conditions in Erlang
Maria ChristakisNational Technical University of Athens, Greece
Joint work with Kostis Sagonas
Maria Christakis Static Race Detection in Erlang
Concurrency A method to better structure programs A means to speed up their execution
A necessity in order to take advantage of multi-core machines which are ubiquitous these days
The catch: Concurrent programming is harder
and more error-prone than its sequential counterpart
Maria Christakis Static Race Detection in Erlang
Erlang Erlang is a strict, dynamically typed
functional programming language
The main implementation of the language is the Erlang/OTP system from Ericsson
Its concurrency model is based on user-level processes that communicate using asynchronous message passing
Maria Christakis Static Race Detection in Erlang
Erlang is not immune to Heisenbugs Its implementation in Erlang/OTP allows for many
kinds of race conditions in programs But Erlang is often advertized as supporting a
shared nothing concurrency model If there is nothing shared between processes, how
can there be race conditions?
System built-ins allow processes to share data
Erlang currently provides no atomicity constructs
Maria Christakis Static Race Detection in Erlang
Data races can happen
If it is possible for another process to succeed in changing the value stored on that variable in between the read and the action in such a way that the action about to be taken is no longer appropriate, then we say that our program has a race condition
When a process reads some variable, it then decides to take some write action based on the value of that variable
Maria Christakis Static Race Detection in Erlang
proc_reg(Name) -> ... case whereis(Name) of undefined -> Pid = spawn(...), register(Name, Pid); Pid -> % already ok % registered end, ...
Data races in the process registry
Maria Christakis Static Race Detection in Erlang
Data races in the process registry
Maria Christakis Static Race Detection in Erlang
run() -> Tab = ets:new(some_tab_name, [public]), Inc = compute_inc(), Fun = fun () -> ets_inc(Tab, Inc) end, spawn_some_processes(Fun).
ets_inc(Tab, Inc) -> case ets:lookup(Tab, some_key) of [] -> ets:insert(Tab, {some_key, Inc}); [{some_key, OldValue}] -> NewValue = OldValue + Inc, ets:insert(Tab, {some_key, NewValue}) end.
Data races in ETS
Maria Christakis Static Race Detection in Erlang
-export([table_func/2]).
table_func(...) -> create_time_stamp_table(), ...
create_time_stamp_table() -> Props = [{type, set}, ...], create_table(time_stamp, Props, ram_copies, false), NRef = case mnesia:dirty_read(time_stamp, ref_count) of [] -> 1; [#time_stamp{data = Ref}] -> Ref + 1 end, mnesia:dirty_write(#time_stamp{data = NRef}).
Data races in mnesia
Maria Christakis Static Race Detection in Erlang
Single-threaded Erlang
A single scheduler picks up processes from a single ready queue
The selected process gets assigned a number of reductions to execute
Each time the process does a function call, a reduction is consumed
A process gets suspended when the number of remaining reductions reaches zero, or when it gets stuck
Maria Christakis Static Race Detection in Erlang
Single-threaded Erlang
Being struck by a lightning seems more likely!
proc_reg(Name) -> ... case whereis(Name) of undefined -> Pid = spawn(...), register(Name, Pid); Pid -> % already ok % registered end, ...
Maria Christakis Static Race Detection in Erlang
Multi-threaded Erlang Since May 2006, a multi-threaded version of the
system has been released, which is the default on multi-core architectures
There are multiple schedulers, each having its own ready queue
Since March 2009, the runtime system employs a redistribution scheme based on work stealing when some scheduler’s run queue becomes empty
Maria Christakis Static Race Detection in Erlang
Dialyzer A DIscrepancy AnaLYZer for ERlang programs Dialyzer has been used by the Erlang community
since 2007, as part of the Erlang/OTP distribution A lightweight static analysis tool for finding
discrepancies in Erlang programs Type errors
Exception-raising code
Unsatisfiable conditions
Redundancies such as unreachable code, etc.
Maria Christakis Static Race Detection in Erlang
Dialyzer
Characteristics of dialyzer (in sequential programs):
Sound for defect detection – not for correctness!
Push-button technology, completely automatic
Fast and scalable
Why dialyzer? Inter-modular call graph and escape analysis Control-flow graphs Type information
Maria Christakis Static Race Detection in Erlang
The analysis
Characteristics:
Sound for either correctness or defect detection!
As precise as possible
Completely automatic
Fast and scalable
Smoothly integrated into dialyzer
Maria Christakis Static Race Detection in Erlang
The analysis: a three-step process
1. Collecting information
Control-flow graphs of functions and closures
Escape analysis
Inter-modular call graph
Sharing/alias analysis
Fine-grained type information (singleton types)
Maria Christakis Static Race Detection in Erlang
The analysis: a three-step process
2. Determining all code points with possible race conditions
Find the root nodes in the inter-modular call graph
Traverse their CFGs using depth-first search
Special cases: Statically known function or closure calls
Unknown higher-order calls
Recursion
Maria Christakis Static Race Detection in Erlang
The analysis: a three-step process
3. Filtering false alarms
Variable sharing
Type information
Characteristics of race conditions
foo(Fun, N, M) -> ... case whereis(N) of undefined -> ..., Fun(M); Pid -> ... end, ...
Maria Christakis Static Race Detection in Erlang
Some optimizations Control-flow graph minimization Avoiding repeated traversals and benefiting from
temporal locality Making unknown function calls less unknown
Maria Christakis Static Race Detection in Erlang
Detecting data races
1 : proc_reg(Name) ->2 : ...3 : case whereis(Name) of4 : undefined ->5 : Pid = spawn(...),6 : register(Name, Pid);7 : Pid -> % already8 : ok % registered9 : end,10: ...
mod.erl:6:The call erlang:register(Name::atom(),Pid::pid()) might fail due to a possible race condition caused by its combination with the erlang:whereis(Name::atom()) in mod.erl on line 3
mod.erl
Maria Christakis Static Race Detection in Erlang
Performance
Maria Christakis Static Race Detection in Erlang
Since September… Our analysis has been publicly released as part of the
latest Erlang/OTP distribution (November 2009)From: Bernard Duggan (Erlang developer)
Sent to us on 27 November 2009
“Our Erlang codebase comprises 5 applications and a few little ancillary bits and pieces on the side – it's about 40k lines. So far it's turned up three race conditions. … Thanks for a brilliant tool.”
Maria Christakis Static Race Detection in Erlang
Race Detection in Erlang (ICFP’09)
QuickCheck: A property-based testing tool
PULSE is a ProTest User Level Scheduler for Erlang that randomly schedules the test case processes and records a detailed trace
A race condition is a possibility of non-deterministic execution that can make a program fail to meet its specification
Maria Christakis Static Race Detection in Erlang
Concluding remarks Future work:
Detection of more kinds of race conditions Detection of more types of concurrency errors Addition of an atomic construct to the language
Besides providing a tool that statically detects data races, we believe that we have also contributed to raising the awareness of the Erlang community on race conditions