60
Introduction to SPIN Radu Iosif ([email protected])

Introduction to SPIN Radu Iosif ([email protected])

Embed Size (px)

Citation preview

Page 1: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Introduction to SPIN

Radu Iosif ([email protected])

Page 2: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

PROMELA (PROcess MEta LAnguage) is:– a language to describe concurrent (distributed)

systems: • network protocols, telephone systems• multi-threaded (-process) programs

– similar with some structured languages (e.g. C, Pascal)

SPIN (Simple Promela INterpreter) is a tool for:– detecting logical errors in the design of systems e.g:

• deadlocks• assertions (e.g. race conditions)• temporal logic formulas (in a future lecture)

Page 3: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Given a PROMELA model (program), SPIN can do:

– a random simulation i.e. it interprets the program• this mode cannot be used in exhaustive verification• useful for viewing error traces

– an exhaustive analysis• considers all possible executions of the program• finds all potential errors, both deadlock and user-specified

Deadlock: – situation in which at least one process remains blocked

forever while waiting for an inexistent event to happen

User specified constraints: – assertions– temporal (never) claims

Page 4: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

PROMELA “Hello World”

The simplest erroneous specification

init {

0;

}

init {

printf(“Hello World\n”);

}

Page 5: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

The SPIN simulation

init { printf(“Hello World\n”);}

SPIN

0: proc - (:root:) creates proc 0 (:init:)

Hello World

1: proc 0 (:init:) line 3 "pan_in" (state 1) [printf(‘Hello World\\n')]

simulation trace

C:\> spin –p hello.prom

Page 6: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

The SPIN analysis (1)

init { 0;} SPIN C:\> spin –a dlock.prom

pan.t pan.m pan.b pan.h pan.c

GCC

pan.exe

Page 7: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

The SPIN analysis (2)

pan.exe dlock.prom.trail

SPIN C:\> spin –p -t dlock.prom

#processes: 1 -4: proc 0 (:init:) line 3 "pan_in" (state 1)1 processes created

error trace

OK

ERROR

Page 8: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

The PROMELA language

Page 9: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Similar to C, for instance:

• all C pre-processor directives can be used

• definitions of types, variables, processes

•if,do,break,goto control flow constructs

Page 10: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Basic types and ranges

At most one enumeration type

bit, bool 0..1

byte 0..255

short - 2^15 - 1 .. 2^15 - 1

int -2^31 – 1 .. 2^31 - 1Warning: type ranges are OS-

dependent (just like in C)

mtype = {one, two, three};

Page 11: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Record types (user-defined)

• look like C structures

typedef S {

short a, b;

byte x;

};

Page 12: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Variables (same C syntax)

Processes (like C procedures)

• the init process (like main in C)– has no parameters

int x, y;

int z = 0;

mtype m = one;

proctype foo(int x, y; bit b){...}

Page 13: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Scoping rules

– variables are global if declared outside any process

– variables are local a process if declared within its proctype declaration

– local variables shadow globals with the same name

Page 14: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Vectors

– declared like variables:

– indexes are zero-based– scoping rules apply (there might be

global and local vectors)

int vector[32];

Page 15: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Expressions

– logical: ||, &&, !– arithmetic: +, -, /, %– relational: >,<,<=,>=,==,!=

– vector access: v[i]– record access: x.f– process creation: run X()

Page 16: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Statements (1) – are execution steps of processes – an important characteristic is

executability:

For instance:

is the (proper) way of expressing something like:

x <= 10;

while(x <= 10);

Page 17: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Statements (2)

• Expression statements• not executable iff expression evaluates to 0

• Assignment statements• always executable

• Skip statements• always executable• do “nothing” (only change control location)

• Print statements• always executable

Page 18: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Statements (3)

• Assert statements

• always executable• expression evaluates to zero => program

exits

• Statements are atomic• in a concurrent program, each statement is

executed without interleaving with other processes

assert( <expression> );

Page 19: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Control flow (1)• Select construct

• What does it do?• if a (random) choice is executable, continues

execution with the corresponding branch• if no choice is executable, the whole select is not

executable• if more than one choice is executable, we say the

selection is non-deterministic

if

:: <choice1> -> <stat11>; <stat12>; …

:: <choice2> -> <stat21>; <stat22>; …

fi;

Page 20: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Control flow (2)• Loop construct

• What does it do?• same as the selection, except that at the

end of a branch it loops back and repeats the choice selection

do

:: <choice1> -> <stat11>; <stat12>; …

:: <choice2> -> <stat21>; <stat22>; …

od;

Page 21: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Control flow (3) (more C syntax)

• The else choice• is executable only when no other choice

is executable

• The break statement• transfers control at the end of loop

• The goto statement• transfers control to a labeled location

Page 22: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Traffic light example

mtype = {red, yellow, green};

byte state = green;

init {

do

:: (state == green) -> state = yellow;

:: (state == yellow) -> state = red;

:: (state == red) -> state = green;

od

}

Page 23: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Concurrency• Processes can spawn other processes

using the run expression

proctype foo(int x; byte y) {…}

init {

int pid;

pid = run foo(256, 255);

/* or simply: */

run foo(256, 255);

}

Page 24: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Interleaving

• Premises:– two or more processes composed of atomic

statements– one processor shared between processes

• Problems:– worst-case complexity is exponential in no of

processes– improper mutex (locking) may cause race

conditions

Page 25: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Complexity

s11

s12

s21

s22

s12

s11

s21

s21

. . .

• how many states can be reached in this example?

• express this number as function of:

K = number of processes

N = number of states/process

Page 26: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Reducing complexity (1)

• if a statement inside atomic is not executable, transfer temporarily control to another process

s12

s11

s21

s21s11

s12

s21

s22

atomic

. . .

Page 27: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Reducing complexity (2)

• if a statement inside d_step is not executable => error (block inside d_step)

• no if, do, break, goto, run allowed inside d_step (i.e., deterministic step)

s11+s12

s21

s21s11

s12

s21

s22

d_step

. . .

Page 28: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Apprentice example• Good apprentice

• Bad apprentice

int counter = 0;

active[2] proctype incr() {

counter = counter + 1;

}

int counter = 0;

active[2] proctype incr() {

int tmp;

tmp = counter + 1;

counter = tmp;

}

atomic

Page 29: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Mutual exclusion (bad) example

proctype B() {

y = 1;

x == 0;

mutex ++;

mutex --;

y = 0;

}

proctype A() {

x = 1;

y == 0;

mutex ++;

mutex --;

x = 0;

}

proctype monitor() {

assert(mutex != 2);

}

Page 30: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Dekker’s mutual exclusion

proctype A() {

x = 1;

turn = Bturn;

(y == 0) || (turn == Aturn);

mutex ++;

mutex --;

x = 0;

}

proctype B() {

y = 1;

turn = Aturn;

(x == 0) || (turn == Bturn);

mutex ++;

mutex --;

y = 0;

}

proctype monitor() {

assert(mutex != 2);

}

Page 31: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Bakery mutual exclusion

• does verification terminate?

proctype A() {

do

:: 1 -> turnA = 1;

turnA = turnB + 1;

(turnB == 0) || (turnA < turnB);

mutex ++; mutex --;

turnA = 0;

od

}

Page 32: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

(Some formal issues)

Page 33: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Formal Concurrent Systems (FCS)

• Mathematical descriptions of concurrent systems

• Important tools for reasoning about such systems

• Composed of states and transitions• Graphical representations of FCS: directed

graphs– nodes represent states, edges are transitions

Page 34: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

FCS preliminaries

• Let A,B be two sets• A relation R is a subset of A x B

– we also write aRb for (a, b) in R

• A function F: A B is a relation such that1. for each a A there exists b in B such that aFb2. such b is unique

• Some notation:– [a b]F is a function G such that G(a) = b

and, for all x other than a, G(x) = F(x)

Page 35: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

States

• Let P be a set of processes P = {p1, … , pn}

• Let L be a set of control locations L = {l1, …, lm}

• Let loc : P L be a control function

• Let I be a set of variables I = {x1, …, xk }

• Let V be a set of values V = {v1, v2, … }

• Let mem : I V be a memory function

• A state is a pair:S = (loc, mem)

Page 36: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Transitions (1)

• A condition C is a boolean expression on a subset of I

• An assignment A is a pair (x, v) from I x V also denoted by x v

• A transition is a 5-tuple:t = (p, ls, ld, C, A)

where ls and ld are elements of L called source and destination locations

Page 37: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Transitions (2)

• A transition t = (p, ls, ld, C, A) is executable in state s = (loc, mem) iff:– loc(p) = ls and C = true

• The result of executing transition t in state s is– s’ = ([p ld]loc, [A]mem)– also denoted by s t s’

Page 38: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Transition systems (TS)• A transition system is a pair TS = (S, s0, T)

– S is a set of states; s0 S is the initial state

– T is a transition relation (S x S)• A TS can be built from each FCS:

– S = {(loc, mem) | loc: P L, mem : I V}– for each two states s, s’ such that s t s’

for some transition t introduce (s, s’) in T• s1,s2, …, sn, … is an (in)finite execution

sequence of the TS iff:– s1 = s0 (initial state condition)– (si, si+1) T (successor condition)

Page 39: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Labeled transition systems (LTS)• LTS = (, S, s0, )

is the alphabet– S is a set of states; s0 S is the initial

state

– : S x P(S) is a transition function• Also known in compilers as finite automata• s1,a1,s2,a2, …, sn,an,sn+1, … is an

(in)finite execution sequence of the LTS iff– s1 = s0 (initial state condition)

– si+1 (si, ai) (successor condition)

Page 40: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Parallel product of LTSs• Given

– LTS1 = (1, S1, s01, 1), – LTS2 = (2, S2, s02, 2)

• The parallel product of LTS1 and LTS is– LTS1 || LTS2 = (, S, s0, ) where: = 1 U 2– S = S1 x S2; s0 = (s01, s02)– (s1’, s2’) ((s1, s2), a) iff either:

• a 1 and s1’ 1(s1, a) or• a 2 and s2’ 2(s2, a)

Page 41: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Synchronous product of LTSs• Given

– LTS1 = (1, S1, s01, 1), – LTS2 = (2, S2, s02, 2)

• The synchronous product of LTS1 and LTS2 is– LTS1 x LTS2 = (, S, s0, ) where: = 1 2– S = S1 x S2; s0 = (s01, s02)– (s1’, s2’) ((s1, s2), a) iff both hold:

• s1’ 1(s1, a) and• s2’ 2(s2, a)

Page 42: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Execution traces, words and languages (1)• Let F S be a set of states• We say LTS = (, S, s0, , F) accepts a

word w = a1, a2, … over iff there exists an execution sequence of LTS:– = s1, a1, s2, a2, …

such that there exists some state from F that repeats infinitely often in

• L(LTS) is the set of all words accepted by LTS

• Also known as the language of LTS

Page 43: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Execution traces, words and languages (2)• Given

–LTS1 = (1, S1, s01, 1, S1), –LTS2 = (2, S2, s02, 2, S2)

– L(LTS1 || LTS2) is the set of all interleavings between words generated by LTS1 and LTS2

– L(LTS1 x LTS2) = L(LTS1) L(LTS2)

– we say an LTS is empty iff L(LTS) =

Page 44: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

(Some formal issues)END

Page 45: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Communication (1)

1. Message passing2. Rendez-vous synchronization

• Both methods rely on channels:

– if dim is 0 then q is a rendez-vous port– otherwise q is an asynchronous

channel

chan q = [<dim>] of {<type>};

chan q; /* just declaration */

Page 46: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Communication (2)

• Send statement

– for rendez-vous channels is executable iff another process is ready to receive at the same time both processes are involved in a rendez-vous

– for asynchronous queues is executable iff the queue is not full

q ! <expr>;

Page 47: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Communication (3)

• Receive statement

– for rendez-vous channels is executable iff another process is ready to send at the same time both processes are involved in a rendez-vous

– for asynchronous queues is executable iff the queue is not empty

q ? <var>;

q ? _;

Page 48: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Communication (4)

• Channel test statement

– same as receive for rendez-vous channels

– for asynchronous queues is executable iff the first value in the queue matches the result of expr

q ? <expr>;

Page 49: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Inter-locking example

chan lock = [1] of bit;

proctype foo(chan q) {

q ? 1;

/* critical section */

q ! 1;

}

init {

lock ! 1;

run foo(lock);

run foo(lock);

}

Page 50: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Recursion example

proctype fact(int n; chan r) {

int tmp;

chan c = [1] of {bit};

if

:: n == 0 -> r ! 1;

:: else ->

run fact(n - 1, c);

c ? tmp; r ! n*tmp;

fi

}

Page 51: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

More advanced issues

Page 52: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Fair transition systems (FTS)• FTS = (, S, s0, , J, C)

– a statement labeled by lab is enabled in a state s iff (s, lab)

– J is the justice set; • any statement labeled by lab J cannot be

continuously enabled but not executed beyond a certain point

– C is the compassion set; • any statement labeled by lab J cannot be

enabled infinitely many times but executed only a finite number of times

Page 53: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Weak fairness (1)

proctype foo(){

do

l0: :: (x == 0) ->

l1: y = y + 1;

:: else ->

l2: break;

od

}

proctype bar(){

m0: x = 1;

m1:

}

Pnueli’s ANY-Y

Page 54: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Weak fairness (2)• An execution trace of ANY-Y:

({(foo,l0), (bar,m0)}, {(x,0), (y,0)}), l0, ({(foo,l1), (bar,m0)}, {(x,0), (y,0)}), l1,

({(foo,l0), (bar,m0)}, {(x,0), (y,1)}), l0, ({(foo,l1), (bar,m0)}, {(x,0), (y,1)}), l1,

({(foo,l0), (bar,m0)}, {(x,0), (y,2)}), l0, ({(foo,l1), (bar,m0)}, {(x,0), (y,2)}), l1,

• The execution is not acceptable because bar never gets a chance to execute the program doesn’t terminate

• Solution: include m0 into the justice set don’t care about executions in which m0 is continuously enabled but never taken

Page 55: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Strong fairness (1)

proctype foo() {

do

l0: :: lock ? 1;

l1: /* critical */

l2: lock ! 1;

od

}

proctype bar() {

do

m0: :: lock ? 1;

m1: /* critical */

m2: lock ! 1;

od

}Pnueli’s MUX-SEM

Page 56: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Strong fairness (2)• An execution trace of MUX-SEM:

({(foo,l0), (bar,m0)}, {(lock, [1])}), l0, ({(foo,l1), (bar,m0)}, {(lock, [])}), l1,

({(foo,l2), (bar,m0)}, {(lock, [])}), l2, ({(foo,l0), (bar,m0)}, {(lock, [1])}), l0,

({(foo,l1), (bar,m0)}, {(lock, [])}), l1, ({(foo,l2), (bar,m0)}, {(lock, [])}), l2,

({(foo,l0), (bar,m0)}, {(lock, [1])}), …

• Not acceptable because bar never gets a chance to enter the critical section, even though he has infinitely often the chance to add m0 to the compassion set

• NOTE: this is not a justice violation because m0 is not continuously enabled, only from time to time

Page 57: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

End labels• An endstate in PROMELA is a state

with no successors• Endstates can be labeled as valid by

introducing labels that start with end– end0,endsome, …

• At the end of each process there is a default valid endstate

• A deadlock is a state with no successors in which at least one process is not in a valid enstate

Page 58: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Timeouts

• A timeout is similar to else or break but:– becomes executable only when no

other transition from any other process is executable

• Provides an escape from deadlock states

Page 59: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Progress labels (a.k.o. strong fairness)• Marked states that must be executed

in order for the program to make progress

• Any infinite execution trace that does not contain at least one progress state is a potential starvation loop

• Like for endstates, label names begin with progress

• Must instruct the model checker to look after non-progress cycles (-l)

Page 60: Introduction to SPIN Radu Iosif (iosif@cis.ksu.edu)

Unless construct

{ stat11;

stat12;

} unless {

stat21;

stat22;

}

• Executes the statements in the main sequence until the first statement in the escape sequence becomes executable