330 likes | 517 Views
Model Checking with SPIN Modeling and Verification with SPIN. ANDREA ORLANDINI – ISTC (CNR). TexPoint fonts used in EMF. Read the TexPoint manual before you delete this box.: A A A. Overview. Model Checking PROMELA Model and Language SPIN Model Checker Example(s) and Demo.
E N D
Model Checking with SPINModeling and Verification with SPIN ANDREA ORLANDINI – ISTC (CNR) TexPoint fonts used in EMF. Read the TexPoint manual before you delete this box.: AAA
Overview • Model Checking • PROMELA Model and Language • SPIN Model Checker • Example(s) and Demo
Common Design Flaws In designing distributed systems: network applications, data communication protocols, multithreaded code, client-server applications. • Deadlock • Livelock, starvation • Underspecification • Unexpected reception of messages • Overspecification • Dead code • Violations of Constraints • Buffer overruns • Array bounds violations Designingconcurrent (software) systemsis so hard that these flaws are mostly overlooked Fortunately, most of these design errors can be detectedusingmodel checkingtechniques
What is model checking? • [Clarke & Emerson 1981]:“Model checking is an automated technique that, given a finite-state model of a system and a logical property, systematically checks whether this property holds for (a given initial state in) that model.” • Model checking tools automatically verify whetherholds, where M is a (finite-state) model of a system and property F is stated in some formal notation. • Problem: state space explosion! • SPIN [Holzmann 1991] is one of the most powerful model checkers. (based on [Vardi & Wolper 1986] Clarke, Emerson, and Sifakis Receive 2007 ACM Turing Award
“Modern” Model Checking • Abstraction is the key activity in both approaches • Here, we deal with pure SPIN, i.e. the classic model checking approach
Verification vs Debugging • Two (extreme) approaches with respect to the application of model checkers. • verification approach: tries to assure the correctness of a detailed model M of the system under validation. • debugging approach: tries to find errors in a model M. • Model checking is most effective in combination with the debugging approach. • Automatic verification is not about proving correctness, but about finding bugs much earlier in the development of a system. (there are exceptions: BIP approach [Henzinger and Sifakis])
Spin and Promela • SPIN = Simple Promela Interpreter • Promela =Process Meta LanguageThe modeling language of SPIN • So it is not a language to build an application! • Strong features : • Powerful constructs to synchronize concurrent processes • Cutting edge model checking technology • Simulation to support analysis (of the models)
System, process, and action. • A system in SPIN consists of a set of interacting and concurrent processes. • Each process is sequential, but possibly non-deterministic. • Each process is built from atomic actions (transition). • Concurrent execution is modeled by interleaving. • Fairness can be impossed.
Recall: interleaving model of concurrency x++ x++ P : print x Q : P || Q :
Promela model • Promela model consists of: • Type declarations • Channel declarations • Variable declarations • Process declarations • [init process] • A Promela model corresponds with a (usually very large, but) finite transition system, so • No unbounded data • No unbounded channels • No unbounded processes • No unbounded process creation
Processes • A process type (proctype) consist of • A name • A list of formal parameters • Local variable declarations • body
Processes • A process • Is defined by a proctype definition • Executes concurrently with all other processes, independent of speed behavior • Communicate with other processes • Using global (shared) variables • Using channels • There may be several processes of the same type • Each process has its own local state: • Process counter (process identifier) • Contents of the local variables
Processes • Processes are created using the run statement • Processes can be created at any point in the execution • Processes start executing after the run statement • Processes can also be created by adding active in front of the proctype declaration
Statements • The body of a process consists of a sequence of statements. A statement is either: • executable: the statement can be executed immediately • blocked: the statement cannot be executed • An assignment is always executable • An expression is also a statement; it is executable if it evaluates to non-zero.
Statements • The skip statement is always executable. • “does nothing”, only changes process’ process counter • • A run statement is only executable if a new process can be created (remember: the number of processes is bounded). • A printf statement is always executable
Statements • Assertexpression; • The assert-statement is alwaysexecutable. • If <expr> evaluates to zero, SPIN will exit with an error, as the <expr> “has been violated”. • The assert-statement is often used within Promela models, to check whether certain propertiesarevalid in a state.
(Enabledness) Expression • Example : • This process has 3 atomic actions. • The action “y==0” • only enabled in a state where the expression is true • it can only be executed when it is enabled; the effect is skip • so, as long as it is disabled, the process will block • if it is not enabled in the current state, due to the interleaving semantics it may become enabled in the next state (by a transition caused by another process) • even if it is enabled in the current state, there is no guarantee the action will be selected for execution; but there is a way in SPIN to impose fairness. active proctype P { x++ ; (y==0) ; x-- }
Example • Use it to synchronize between processes : • // both will terminate, but forcing Q to finish last byte x=0 , y=0 active proctype P { x++ ; (y>0) ; x-- } active proctype Q { (x>0) ; y++ ; (x==0) ; y-- }
Multiprogramming is tricky…. • E.g. one or more processes can become stuck (deadlocked) : (hence the need for verification!) byte x=0 , y=0active proctype P { x++ ; (y>0); (y==0) }active proctype Q { y++ ; (x>0) ; (x==0) ; y-- }
Non-determinism • Non-determinism can be used to abstractly model alternate behavior:active proctype client1() { do :: r ! REQ1 // spamming requests :: g1 ? GRANTED ; ... ; rstatus = 0 :: g1 ? GRANTED ; rstatus= err // sometimes error :: break // sometimes customer is impatient od ...
Scope • There are only 2levels of scope: • global var (visible in the entire sys) • local var (visible only to the process that contains the declaration)
Channels • for exchanging messages between processes • finite sized and asynchronously, unless you set it to size 0 synchronous channel • Syntax : c ! 0 sending over channel c; blocking if c is full c ? x receives from c, transfer it to x; blocking if c is empty • There are some more exotic channel operations : checking empty/full, testing head-value, copying instead of receiving, sorted send, random receive ... check out the Manual chan c = [0] of {bit}; chan d = [2] of {mtype, bit, byte}; chan e[2] = [1] of {mtype, record};
Assertion • Thanks to built-in non-determinism in the interleaving semantics, we can also use assertion to specify a global invariant !// implying that at any time during the run x is either 0 or 1 byte x=0 , y=0 active proctype P { x++ ; (y>0) ; x-- }active proctype Q { (x>0) ; y++ ; (x==0) ; y--} active proctype Monitor { assert ((x==0 || x==1)) }
End state • When a process P fails to reach its terminal (end) state: • Then it was locked error. • Maybe this P is not supposed to reach end-state suppress end-state checking with SPIN option. • The terminal state is by default just the textual end of of P’s code. • You can specify additional terminal states by using end-label: • Of the form “end*”
State • Each (global) state of a system is a “product” of the states of its processes. • E.g. Suppose we have: • One global var byte x • Process P with byte y • Process Q with byte z • Each system state should describe: • all these variables • Program counter of each process • Other SPIN predefined vars • Represent each global state as a tuple … this tuple can be quite big.
Watch out for state explosion! • Size of each state: > 96 bits • Number of possible states (232) 3 = 296 • Far too huge • Focus on the critical aspect of your model; abstract from data when possible. intx,y,z ; P { do :: x++ od }Q { do :: y++ od }R { do :: x/=y z++ od }
(X)SPIN Architecture •deadlocks •safetyproperties •livenessproperties spin random guided interactive ϕ LTL Translater Simulator Promela model M Xspin Spin Verifier Generator editingwindow simulationoptions verificationoptions MSCsimulation window C program pan.* counter example false checker pan.exe
The stack • To save space SPIN does not keep a stack of states (large!), but rather a stack of action-IDs (small!) • Though this requires computing action-undo when backtracking
Verifier’s output assertion violated !((crit[0]&&crit[1])) (at depth 5) // computation depth ... Warning: Search not completed Full statespace search for: ... never-claim - (not selected) assertion violations + invalid endstates + State-vector 20 byte, depth reached 7, errors: 1 // max. stack depth 24 states, stored // states stored in hash table 17 states, matched // states found re-revisited 41 transitions (= stored+matched) 0 atomic steps hash conflicts: 0 (resolved) (max size 2^19 states) 2.542 memory usage (Mbyte)
Specifying LTL properties • In Xspin via the LTL manager; available operators ; somewhat silly interface • SPIN then generates the Buchi automaton for this LTL formula; called “Never Claim” in SPIN. [](ok1 && !ok2) #define ok1 crit[1] #define ok2 crit[2]
Example of a Never Claim • Here is the never-claim of []<>p (the Buchi of []<>p = <>[]p) • This is automatically generated by SPIN never {do:: p ; break :: skipod ; accept : do :: !p ; skip od } Error if accept is reachable in the lock-step execution, and from there a cyclic run can be found.
Demo Time • Just to have a rough idea of how SPIN works!!!