using static analysis to detect type errors &...

66
Using Static Analysis to Detect Type Errors & Concurrency Defects in Erlang Programs Kostis Sagonas National Technical University of Athens, Greece Uppsala University, Sweden

Upload: others

Post on 22-May-2020

23 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Using Static Analysis to Detect Type Errors & Concurrency Defects in Erlang Programs

Kostis Sagonas

National Technical University of Athens, GreeceUppsala University, Sweden

Page 2: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

Erlang A concurrent programming language

− syntax influenced from Prolog− functional: strict, higher-order, pattern

matching, guards, list comprehensions− dynamically typed

The main implementation of Erlang is the Erlang/OTP system from Ericsson

Successfully used within telecommunications and in application domains which require high degree of concurrency and/or fault tolerance

Page 3: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

Dynamically typed languages

... such as Erlang can be seen as unityped:− Only one type: term() or any()‏

However, some primitive functions are only defined on subtypes of all terms and their arguments need to be checked at runtime

Type safety is not an issue as it is provided by the runtime system: all terms are tagged with their type, which is checked in primitive operations

However, programmers often make mistakes that a statically typed language would normally catch

Page 4: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

Type system to the rescue?

Type system: an analysis that is fast, sound for correctness– “well-typed programs do not go

wrong”• w.r.t. some kinds of errors

– pessimistic and inflexible: if cannot prove safety, reject the program

Page 5: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Using Static Analysis for Detecting Type Errors

Page 6: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

False error reports: show-stopper

Flanagan et al. (ESC/Java people), 2002:− “[T]he tool has not reached the desired level of cost

effectiveness. In particular, users complain about an annotation burden that is perceived to be heavy, and about excessive warnings about non-bugs, particularly on unannotated or partially-annotated programs.”

Rutar et al., 2004:− > 9k NPE warnings in 170k non commented source statements− “[T]here are too many warnings to be easily useful by

themselves.”

Page 7: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

The problem statement

Infer types for all functions in the program, without imposing any constraints that the programmer never intended

foo([],L) -> L;foo([H|T],L) -> [H|foo(T,L)].

foo(list(), any()) -> any()‏

To be sound for defect detection, the inferred types have to respect the operational semantics of the language

Should this type be different if the function was called append instead of foo?

Page 8: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Women, Men, and Restroom Signs

Page 9: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

Restroom signs in the U.S.A.

Page 10: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

Restroom signs at NTUA, Greece

Page 11: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

Tempting conclusion In the U.S., everything is forbidden unless it is

allowed In Greece, everything is allowed unless it is

forbidden

That’s not the point of the story...

Page 12: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

More permissive?

Page 13: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

Which is better?

+− More restrictive: no dogs allowed− More permissive: what if both?

-− Too restrictive: what if neither? (e.g., boy/girl)

Page 14: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

Which is better?

+− More permissive: what if neither?

“just visiting your planet”

-− Too permissive: dogs allowed− Too restrictive: what if both?

Page 15: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

All is a matter of desired specification No definition is better by default

− all is a matter of desired behavior− usual precision and recall metrics for quality

what percentage of allowed behaviors are desired? what percentage of desired behaviors are allowed?

Page 16: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Back to Detecting Type Errors by Static Analysis...

Page 17: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

The moral of all this is... Being sound for correctness is not always a

superior approach− restricts expressiveness− rejects valid programs

think of sound analyses for “no division by zero”

All depends on desired behavior− for defect detection tools the goal is to find definite

bugs, rather than to prove correctness− soundness for incorrectness is very valuable!

Page 18: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

Type analysis for defect detection

The inferred types should:− Be easy to interpret by the programmer− Never lie: Capture all possible, however unintended,

uses of functions The type inference algorithm should:

− Be completely automatic Not require any user annotations Not require any type declarations

− Handle cases where not all code is available− Be relatively fast

Page 19: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

Dialyzer

“A DIscrepancy AnaLYZer for ERlang programs” Part of the Erlang/OTP distribution since 2007 A lightweight static analysis tool for finding

discrepancies in Erlang programs− Managed to uncover many bugs in large,

well-tested, commercial applications− Heavily used in the Erlang community

Page 20: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

Dialyzer

Characteristics of dialyzer (for type error detection):

Sound for defect detection – not for correctness!

Push-button technology, completely automatic

Fast and scalable

Very successful

Page 21: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

An Erlang implementation of and

> and(true, true).true> and(false, true).false> and(false, gazonk).false> and(3.14, false).false

Trial runs

and(true, true) → true;and(false, _) → false;and(_, false) → false.

Erlang program

bool() ::= true | false

Page 22: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

An Erlang implementation of and

> and(true, true).true> and(false, true).false> and(false, gazonk).false> and(3.14, false).false

Trial runsHM-type signature

and(bool(), bool()) → bool()‏

and(true, true) → true;and(false, _) → false;and(_, false) → false.

Erlang program

Page 23: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

An Erlang implementation of and

> and(true, true).true> and(false, true).false> and(false, gazonk).false> and(3.14, false).false

Trial runs

Typing inferred by algorithm from S. Marlow and P. Wadler, “A practical subtyping system for Erlang”

Subtyping signature

and(any(), false) → bool()‏

and(true, true) → true;and(false, _) → false;and(_, false) → false.

Erlang program

Page 24: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

A quick look at inferred domains

Dynamic typing domain

Static typing domain

We need to capture all of the dynamic domain!

Page 25: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

Definition:

A success typing for a function f is a type signature, α→β , such that whenever an application f(x) reduces to a value v, then x ∈ α and v ∈ β .

Intuition:− If the arguments are in the domain of the function

the application might succeed, but − if they are not, the application will definitely fail.

Success typings

v

Page 26: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

Success typing domain

Function domains revisited

Dynamic typing domain

Static typing domain

Page 27: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

Recap

HM-type

and(bool(), bool()) → bool()‏

Subtyping

(any(), 'false') → bool()‏

Success typing

and(any(), any()) → bool()‏

and(true, true) → true;and(false, _) → false;and(_, false) → false.

Erlang program

Page 28: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

Two sides to the story

Well-typed programs do not go wrong!

Ill-typed programs will surely fail!

Pessimism: If we cannot prove type safety we must reject the program.

Optimism: If we cannot detect a type clash we need to accept the program as it might work.

Static typing view Success typing view

Page 29: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

Inferring success typings There is a most general success typing for all

functions of a certain arity (any()) → any() for all functions of arity 1 (any(), any()) → any() for all functions of arity 2 ...

The aim of the inference algorithm is to reduce both the domain and the range of the success typing as much as possible without excluding any valid terms

Page 30: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

The inference algorithm [PPDP’06] Constraint-based algorithm

− Constraint generation− Constraint solving, bottom-up per SCC

Constraints are organized in disjunctions and conjunctions of subtype constraints

Conjunctions come from straight-line code and disjunctions come from choices (case statements)‏

( ) ( ) ( )nn CC|CC|TT::=C ∨…∨∧…∧⊆ 1121

Page 31: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

Some examples

b(X) when is_integer(X) → a(X).

c(X) →case b(X) of

42 → foo;gazonk → bar

end.

%% b(integer()) → integer() | float().

%% c(integer()) → foo.

a(X) → X + 1.

%% a(integer() | float()) → integer() | float().

Page 32: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

More examples

foo(X) when is_integer(X) → X + 1;foo(X) → atom_to_list(X).

%% foo(integer() | atom()) → integer() | list().

gazonk(X) when is_atom(X) → X + 42.%% gazonk(none()) → none()‏

Page 33: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

A higher-order example

foo() → F = fun (X) when is_integer(X) → 54 end, h(F).

%% foo() → none().

h(F) → F(true) + 42.%% h((any()) → any()) → number()‏

Page 34: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

A slight disturbance...

length_1([]) → 0;length_1([_|T]) → length_1(T) + 1.

length_2(L) → length_3(L, 0).

length_3([], N) → N;length_3([_|T], N) → length_3(T, N+1).

%% length_1(list()) → non_neg_integer()‏

%% length_3(list(), any()) → any()‏

%% length_2(list()) → any()‏

Page 35: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

Module system to the rescue In Erlang, the module system cannot be bypassed

− Code resides in modules− Modules have declared interfaces (exported functions)‏

Since the module system protects local functions from arbitrary use, we can collect the types of the parameters of all call sites of these functions

We can use this information to restrict the domains of module-local functions

− “refined success typings”

Page 36: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

The length example revisited

-module(my_list_utils).-export([length_2/1]).

length_2(L) → length_3(L, 0).

length_3([], N) → N;length_3([_|T], N) → length_3(T, N+1).

%% length_2(list()) → any().

%% length_3(list(), any()) → any().%% length_3(list(), non_neg_integer()) → non_neg_integer().

%% length_2(list()) → non_neg_integer().

Page 37: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

Adding function specifications

-module(my_list_utils).-export([length_2/1]).

length_2(L) → length_3(L, 0).

length_3([], N) → N;length_3([_|T], N) → length_3(T, N+1).

-spec length_2(list()) → non_neg_integer().

Page 38: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

Adding contracts

-module(my_list_utils).-export([length_2/1]).

length_2(L) → length_3(L, 0).

length_3([], N) → N;length_3([_|T], N) → length_3(T, N+1).

-spec length_2(list(atom())) → integer().

Page 39: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

How Erlang modules used to look like

Page 40: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

How modern Erlang modules look

Page 41: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Using Static Analysis for Detecting Concurrency Defects

Page 42: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

Concurrency

A method to better structure programs A means to speed up their execution A necessity these days??

The catch: Concurrent programming is harder

and more error-prone than its sequential counterpart

Page 43: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

Data race detection in Erlang

Erlang’s concurrency model is based on user-level processes that communicate via asynchronous message passing

− copying semantics (“shared-nothing”)‏ If there is nothing shared between processes, how

can there be data races?

System built-ins allow processes to share data Erlang currently provides no atomicity constructs

Page 44: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

What is considered a data race?

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 the 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

Page 45: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

proc_reg(Name) -> ... case whereis(Name) of undefined -> Pid = spawn(...), register(Name, Pid); Pid -> % already ok % registered end, ...

Data races in the process registry

Page 46: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

Data races in the process registry

Page 47: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

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

Page 48: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

-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

Page 49: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

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

Page 50: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

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, ...

Page 51: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

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

Page 52: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

Race analysis in Dialyzer

Characteristics:

Sound for either correctness or defect detection

Completely automatic

Fast and scalable

Smoothly integrated into dialyzer

Page 53: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

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)‏

Page 54: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

The analysis: a three-step process

2. Determining all code points with possible race conditions

− Find the root nodes in the forest of call graphs

− Traverse their CFGs using DFS

− Special cases: Statically known function or closure calls

Unknown higher-order calls

Recursion

Page 55: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

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, ...

Page 56: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

Some optimizations Control-flow graph minimization Avoiding repeated traversals and benefiting from

temporal locality Making unknown function calls less unknown

Page 57: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

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

Page 58: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

Effectiveness and Performance

Page 59: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

Current status and impact The race analysis has been publicly released as part of

the latest Erlang/OTP distribution (mid November 2009)From: Bernard Duggan (Erlang developer)‏

Sent 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.”

Page 60: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

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

Page 61: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

Current and Future Work Extend dialyzer to detect:

− more kinds of race conditions− more types of concurrency errors− violations in the requirements of Erlang behaviours

(concurrency design patterns)‏ Extend the language of -spec’s to specify

concurrency properties and requirements Generating tests from -spec’s

Page 62: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Gracias!

Page 63: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

Page 64: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

What are types good for? Document programmers' intentions Can be used to prove properties of programs

− e.g., type safety, ... Often help the compiler generate better code by

avoiding some checks during runtime Detect some programmer errors

Page 65: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

Erlang terms Primitive terms:

− integers : 42, 1593405849584548049385− floats : 2.56, 3.14 − atoms : foo, true − binaries : <<0100100111011>>

Structured terms:− tuples : {foo, 42}, {1, 2, 3}− lists : [1, 2, 3.14]

Higher-order terms:− funs : fun(X) when is_atom(X) -> X == a end

Page 66: Using Static Analysis to Detect Type Errors & …gpd.sip.ucm.es/charlas/20100616KostisSagonas/sagonasSld.pdfUsing Static Analysis to Detect Type Errors & Concurrency Defects in Erlang

Kostis Sagonas Dialyzer @ UCM 2010

Refined success typings Definition:

− Let be a function with success typing . A refined success typing for is a typing on the form , such that

− and , and− For all for which the application reduces to a

value, .

f α β

α ' β '

α '⊆α β '⊆β

p f p

f p ∈ β '

f