Easier to read with cream paper, a tint, more contrast or larger text? Choose your colours and text, once, for every page.

Free lesson

Finding a race condition with SPIN

After this lesson: I can find a race between two processes in a trace.

60 min lesson3 commandsFormal methods lab: Z3, SPIN, TLA+ and Alloy on one VM

A race condition needs one exact order

A race condition is a fault that appears only when two processes run their steps in one particular order. A test usually runs the same order every time, so it misses the fault.

SPIN is a model checker that tries every order and prints the one that breaks the program.

By the end of this lesson

Note

I can find a race between two processes in a trace.

Key words

WordWhat it meansExample
Processa program that runs its own steps
Shared variablea value that two processes can both change
Interleavingone order in which the steps of two processes mix
Race conditiona fault that depends on the order of steps
Assertiona rule the model checker tests at one pointassert(till == 20)
Tracethe list of steps that led to a failure

The cells students fill in are left blank in this preview.

Two cashiers can lose money

Two cashiers each add 10 pounds to a shared till. Each one does two steps: read the till, then write what it read plus 10.

If cashier A reads, then B reads, then both write, each wrote 10. The till holds 10, not 20. One payment is lost.

Worked example: one bad order

StepWhoWhat happensTill after
1Areads the till and sees 00
2Breads the till and sees 00
3Awrites 0 + 1010
4Bwrites 0 + 1010

The cells students fill in are left blank in this preview.

The number of orders grows fast

Two processes of two steps each can mix in 6 ways. Only 2 of them are safe: A finishes before B starts, or the other way round.

Add steps and the count explodes, as the table shows. A test runs one order. A model checker tries all of them.

Steps in each process and orders to try

Steps in each processOrders to try
12
26
320
470
5252

The cells students fill in are left blank in this preview.

Promela writes a process as steps

Promela is the language SPIN reads. A proctype is a process, and active [2] starts two copies of it. Each statement is one step, and the checker may switch to the other process after any step.

A statement is usually ended by a semicolon. -> means the same, so these models use it to read as "then". The table explains the file.

Worked example: the till model line by line

LineWhat it says
byte till = 0the shared till starts at 0
byte done = 0counts the cashiers that have finished
active [2] proctype cashier() {start two cashier processes
seen = till -> till = seen + 10 -> done++read, then write plus 10, then count one finished
active proctype audit() {a third process that checks the end
done == 2 -> assert(till == 20)wait until both finished, then demand 20

The cells students fill in are left blank in this preview.

Write the model to a file

Command
printf '%s\n' 'byte till = 0' 'byte done = 0' 'active [2] proctype cashier() {' '  byte seen' '  seen = till -> till = seen + 10 -> done++' '}' 'active proctype audit() {' '  done == 2 -> assert(till == 20)' '}' > till.pml

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Check every order

Command
spinrun till.pml | grep -E 'pan:1|errors'

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Replay the bad order

Command
spin -t -p till.pml

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

A common mistake

Warning

Many people think running the program many times will show a race. A race needs one exact order of steps. A normal run may pick the same order a million times. A model checker tries every order, so it finds the race in one run.

About this lab and its source: Formal methods lab: Z3, SPIN, TLA+ and Alloy on one VM

Teaching a class? Set this module for your students with a teacher guide, marked assignments and a lab for every student.