0% found this document useful (0 votes)
28 views

Spin Lecture

Promela/SPIN is a modeling language and model checker for verifying correctness of concurrent systems. Promela is used to specify systems as processes that communicate through message passing or shared variables. SPIN compiles Promela models into C code and performs an explicit-state model checking to verify properties like deadlocks, assertions and LTL formulas. Key features include process synchronization, channels for communication, and verification of mutual exclusion algorithms like Peterson's solution.

Uploaded by

infcom
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
28 views

Spin Lecture

Promela/SPIN is a modeling language and model checker for verifying correctness of concurrent systems. Promela is used to specify systems as processes that communicate through message passing or shared variables. SPIN compiles Promela models into C code and performs an explicit-state model checking to verify properties like deadlocks, assertions and LTL formulas. Key features include process synchronization, channels for communication, and verification of mutual exclusion algorithms like Peterson's solution.

Uploaded by

infcom
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 46

Promela/SPIN

Acknowledgements: These notes used some of the material presented by Flavio Lerda as part of Ed Clarkes model-checking course

SPIN

For checking correctness of process interactions


Specified using buffered channels, shared variables or combination Focus: asynchronous control in software systems Promela program-like notation for specifying design choices
Models are bounded and have countably many distinct behaviors

Generate a C program that performs an efficient online verification of the systems correctness properties Types of properties:
Deadlock, violated assertions, unreachable code System invariants, general LTL properties

Random simulations of the systems execution Proof approximation 2

Explicit State Model Checker


Represents Visits

the system as a finite state machine

each reachable state (state space) explicitly (using Nested DFS) on-the-fly computation partial order reduction memory usage

Performs Uses

Efficient

State compression
Bit-state hashing
Version

4:

Uninterpreted C code can be used as part of Promela model

High Level Organization


LTL formula Promela Model

LTL Translator
Buchi Automaton Buchi Translator

Promela Parser The Buchi automaton is turned into a Promela Abstract Syntax Tree process and composed Automata Automata with the rest of the system. Generator The generated verifier is C Generator specific to the model and property we started with. C Code
C Compiler Pan Verifier

Verification Result

Promela (Process Meta Language)

Asynchronous composition of independent processes


Communication using channels and global variables Non-deterministic choices and interleavings Based on Dijkstras guarded command language
Every statement guarded by a condition and blocks until condition becomes true Example:
while (a == b)
skip /* wait for a == b */

vs
(a == b)

Process Types

State of variable or message channel can only be changed or inspected by processes (defined using proctype)
; and -> are statement separators with same semantics.
-> used informally to indicate causal relation between statements Example:
byte state = 2; proctype A() { (state == 1) -> state = 3 } proctype B() { state = state -1 }

state here is a global variable

Process Instantiation

Need to execute processes


proctype only defines them

How to do it?
By default, process of type init always executes run starts processes Alternatively, define them as active (see later)

Processes can receive parameters


all basic data types and message channels. Data arrays and process types are not allowed.
Example:
proctype A (byte state; short foo) { (state == 1) -> state = foo } init { run A(1, 3) }

Example

As mentioned earlier, no distinction between a statement and condition.


bool a, b; proctype p1() { a = true; a & b; a = false; } proctype p2() { b = false; a & b; b = true; } init { a = false;

These statements are enabled only if both a and b are true. In this case b is always false and therefore there is a deadlock.

b = false; run p1(); run p2(); }

An Example
mtype = { NONCRITICAL, TRYING, CRITICAL }; mtype state[2]; proctype process(int id) { beginning: noncritical: state[id] = NONCRITICAL; if :: goto noncritical; :: true; fi; trying: state[id] = TRYING; if :: goto trying; :: true; fi; critical: state[id] = CRITICAL; if :: goto critical; :: true; fi; goto beginning;} init { run process(0); run process(1) }

At most one mtype can be declared

NC

Other constructs

Do loops
do :: count = count + 1; :: count = count - 1; :: (count == 0) -> break od

10

Other constructs

Do loops
Communication over channels
proctype sender(chan out) { int x; if ::x=0; ::x=1; fi out ! x; }

11

Other constructs

Do loops
Communication over channels Assertions
proctype receiver(chan in) { int value; out ? value; assert(value == 0 || value == 1) }

12

Other constructs

Do loops
Communication over channels Assertions

Atomic Steps
int value; proctype increment() { atomic { x = value; x = x + 1; value = x; } }

13

chan qname = [16] of {short}

Message Passing

qname!expr writing (appending) to channel qname?expr reading (from head) of the channel qname??expr peaking (without removing content) qname!!expr checking if there is room to write can declare channel for exclusive read or write: chan in, out; xr in; xs out; qname!exp1, exp2, exp3 writing several vars qname!expr1(expr2, expr3) type and params qname?vari(var2, var3)
qname?cons1, var2, cons2 can send constants Less parameters sent than received others are undefined More parameters sent remaining values are lost Constants sent must match with constants received

14

Message Passing Example


proctype A(chan q1) { chan q2; q1?q2; q2!123 } proctype B(chan qforb) { int x; qforb?x; print(x=%d\n, x) } init { chan qname = [1] of {chan }; chan qforb = [1] of {int }; run A(gname); run B(qforb); qname!qforb }

Prints:

123 15

Randez-vous Communications

Buffer of size 0 can pass but not store messages


Message interactions by definition synchronous

Example:
#define msgtype 33
chan name = [0] of { byte, byte }; proctype A() { } proctype B() { } init { } atomic { run A(); run B() } byte state; name?msgtype(state) name!msgtype(123); name!msgtype(121); /* non-executable */

16

Randez-Vous Communications (Contd)

If channel name has zero buffer capacity:


Handshake on message msgtype and transfer of value 123 to variable state. The second statement will not be executable since no matching receive operation in B

If channel name has size 1:


Process A can complete its first send but blocks on the second since channel is filled. B can retrieve this message and complete. Then A completes, leaving the last message in the channel

If channel name has size 2 or more:


A can finish its execution before B even starts

17

Example protocol

Channels Ain and Bin


to be filled with token messages of type next and arbitrary values (ASCII chars) by unspecified background processes: the users of the transfer service

These users can also read received data from the channels Aout and Bout

The channels are initialized in a single atomic statement


And started with the dummy err message.

18

Example Contd
mtype = {ack, nak, err, next, accept}; proctype transfer (chan in, out, chin, chout) { byte o, I; in?next(o); do :: chin?nak(I) -> out!accept(I); chout!ack(o) :: chin?ack(I) -> out!accept(I); in?next(o); chout!ack(o) :: chin?err(I) -> chout!nak(o) od }

19

Example (Contd)
init {
chan AtoB chan BtoA chan Ain chan Bin chan Aout chan Bout = [1] if { mtype, byte }; = [1] of { mtype, byte }; = [2] of { mtype, byte }; = [2] of { mtype, byte }; = [2] of { mtype, byte }; = [2] of { mtype, byte };

atomic { run transfer (Ain, Aout, AtoB, BtoA); run transfer (Bin, Bout, BtoA, AtoB); } AtoB!err(0) }

20

Mutual Exclusion
Petersons

solution to the mutual exclusion

problem

flag0=1

turn=0 flag1 == 0 || turn == 1

flag0=0

flag1 != 0 && turn != 1


Critical Section

21

Mutual Exclusion in SPIN


bool turn; bool flag[2]; proctype mutex0() { again: flag[0] = 1; flag0=1

turn = 0;
(flag[1] == 0 || turn == 0); /* critical section */ flag1 == 0 || turn == 1 flag[0] = 0; goto again; } Critical Section flag1 != 0 && turn != 1 turn=0 flag0=0

22

Mutual Exclusion in SPIN


bool turn, flag[2]; active [2] proctype user() { assert(_pid == 0 || __pid == 1); again: flag[_pid] = 1; turn = _pid; (flag[1 - _pid] == 0 || turn == 1 - _pid); /* critical section */ flag[_pid] = 0; goto again; } _pid: Identifier of the process assert: Checks that there are only at most two instances with identifiers 0 and 1

23

Mutual Exclusion in SPIN


bool turn, flag[2];
byte ncrit; active [2] proctype user() { assert(_pid == 0 || __pid == 1); again: flag[_pid] = 1; turn = _pid; (flag[1 - _pid] == 0 || turn == 1 - _pid); ncrit++; assert(ncrit == 1); /* critical section */ assert: ncrit--; Checks that there is always at most one process in the critical section flag[_pid] = 0; goto again; ncrit: Counts the number of processes in the critical section

24

Verification

Generate, compile and run the verifier


to check for deadlocks and other major problems:
$ spin a mutex $ cc O pan pan.c $ pan full statespace search for: assertion violations and invalid endstates vector 20 bytes, depth reached 19, errors: 0 79 states, stored 0 states, linked 38 states, matched total: 117 hash conflicts: 4 (resolved) (size s^18 states, stack frames: 3/0) unreached code _init (proc 0); reached all 3 states unreached code P (proc 1): reached all 12 states

25

Mutual Exclusion
Verifier:

Assertion can be violated

Can use -t -p to find out the trace


Or use XSpin

Another

way of catching the error

Have another monitor process ran in parallel Allows all possible relative timings of the processes Elegant way to check validity of system invariant

26

bool turn, flag[2]; byte ncrit;

Mutual Exclusion in SPIN

active [2] proctype user() { assert(_pid == 0 || __pid == 1); again: flag[_pid] = 1; turn = _pid; (flag[1 - _pid] == 0 || turn == 1 - _pid);

ncrit++; /* critical section */ ncrit--;


flag[_pid] = 0; goto again; } active proctype monitor() { assert (ncrit == 0 || ncrit == 1) }

27

Finally,
Can

specify an LTL formula and run the modelchecker


#define p count <= 1 LTL claim: [] p

Example:

Note: LTL

all variables in LTL claims have to be global!

claim gets translated into NEVER claim and stored either in .ltl file or at the end of model file
Only one LTL property can be verified at a time

Parameters

can be set using XSpin

Depth of search, available memory, etc. 28

Mutual Exclusion in SPIN


bool turn, flag[2]; bool critical[2]; active [2] proctype user() { assert(_pid == 0 || __pid == 1); again: flag[_pid] = 1; turn = _pid; (flag[1 - _pid] == 0 || turn == 1 - _pid); critical[_pid] = 1; /* critical section */ critical[_pid] = 0; flag[_pid] = 0; goto again; } LTL Properties: [] (critial[0] || critical[1])

[] <> (critical[0]) [] <> (critical[1])


[] (critical[0] -> (critial[0] U (!critical[0] && ((!critical[0] && !critical[1]) U critical[1])))) [] (critical[1] -> (critial[1] U (!critical[1] && ((!critical[1] && !critical[0]) U critical[0])))) Note: critical[ ] is a global var!

29

Alternatively,
#define p ncrit <= 1 #define q ncrit = 0 bool turn, flag[2]; byte ncrit; LTL Properties: [] (p) []<> (!q)

active [2] proctype user() { assert(_pid == 0 || __pid == 1); again: flag[_pid] = 1; turn = _pid; (flag[1 - _pid] == 0 || turn == 1 - _pid);
ncrit++; /* critical section */ ncrit--; flag[_pid] = 0; goto again;

30

Command Line Tools

Spin
Generates the Promela code for the LTL formula
$ spin f []<>p The proposition in the formula must correspond to #defines

Generates the C source code


$ spin a source.pro The property must be included in the source

Pan
Performs the verification
Has many compile time options to enable different features Optimized for performance

31

Xspin

GUI for Spin

32

Simulator
Spin

can also be used as a simulator

Simulated the Promela program


It

is used as a simulator when a counterexample is generated


Steps through the trace The trace itself is not readable

Can

be used for random and manually guided simulation as well

33

A few examples

Alternating Leader

Bit Protocol

Election

Alternating Bit Protocol


Two

processes want to communicate

They

want acknowledgement of received messages window of one message values of the identifier message is identified by one bit

Sending Each

Alternating

35

Alternating Bit Protocol


Sender msg0 ack0 msg1 ack1 msg0 Receiver

ack0
msg1

36

Alternating Bit Protocol


Sender msg0 ack1 msg0 ack0 Receiver

37

Alternating Bit Protocol


Sender msg0 msg0 ack0 msg1 ack1 Receiver

38

Sender Process
active proctype Sender() { do :: if :: receiver!msg0; :: skip fi; do :: sender?ack0 -> break :: sender?ack1 :: timeout -> if :: receiver!msg0; :: skip fi; od;
::
if :: receiver!msg1; :: skip fi; do :: sender?ack1 -> break :: sender?ack0 :: timeout -> if :: receiver!msg1; :: skip fi; od; od; }

39

Receiver Process
active proctype Receiver() { do :: do :: receiver?msg0 -> sender!ack0; break; :: receiver?msg1 -> server!ack1 od do :: receiver?msg1 -> sender!ack1; break; :: receiver?msg0 -> server!ack0 od od } mtype = { msg0, msg1, ack0, ack1 } chan sender = [1] of { mtype }; chan receiver = [1] of { mtype };

40

Summary

Distinction between behavior and requirements on behavior


Which are checked for their internal and mutual consistency

After verification, can refine decisions towards a full system implementation


Promela is not a full programming language

Can simulate the design before verification starts

46

Comments
DFS

does not necessarily find the shortest counterexample


There might be a very short counterexample but the verification might go out of memory

If we dont finish, we might still have some sort of a result (coverage metrics)

47

On-The-Fly
System The For

is the asynchronous composition of processes


global transition relation is never build each state the successor states are enumerated using the transition relation of each process

48

Visited Set
Hash

table

Efficient for testing even if the number of elements in it is very big ( 106)
Reduce

memory usage the number of states


When a transition is executed only a limited part of the state is modified

Compress each state


Reduce

Partial Order Reduction

49

Compression
P0 x=0 P0 x=1 Q0 {1} P0 x=0 P1 y=0

i=0 j=0

0 0 1 0 0 2

3
2 1 0 i=0 j=0

3
2 1 0 P1 y=0

3
2 1 0 Q0 {1}

P0 x=1
P0 x=0

53

References

http://spinroot.com/
Design and Validation of Computer Protocols by Gerard Holzmann The Spin Model Checker by Gerard Holzmann

An automata-theoretic approach to automatic program verification, by Moshe Y. Vardi, and Pierre Wolper
An analysis of bitstate hashing, by G.J. Holzmann An Improvement in Formal Verification, by G.J. Holzmann and D. Peled Simple on-the-fly automatic verification of linear temporal logic, by Rob Gerth, Doron Peled, Moshe Vardi, and Pierre Wolper A Minimized automaton representation of reachable states, by A. Puri and G.J. Holzmann 58

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy