Logic Model Checking Lecture Notes 2:18 Caltech 101b.2 January-March 2005 Course Text: The Spin Model Checker: Primer and Reference Manual Addison-Wesley 2003, ISBN 0-321-22862-6, 608 pgs. course web page • http://spinroot.com/spin/Doc/course/ – pdf’s for lectures and background material (Standish survey, NIST report) – will have assignments and any additional materials • to do: – install a copy of Spin and start experimenting with it • http://spinroot.com/spin/ – on Windows PCs with cygwin installed (www.cygwin.com): • download the executable spin422.exe and copy it to /bin/spin.exe • download the tcl/tk gui xspin422.tcl and copy it to /bin/xspin – on Linux or Unix systems: compile from the sources and install spin and xspin in your /home/user/bin • questions: [email protected] Logic Model Checking [2 of 18] 2 Course Outline • introduction – what makes designing reliable distributed systems so hard? – the concept of a verification model • modeling concurrency, expressing correctness claims • using abstraction effectively • theoretical foundation – automata and logic – verification algorithms – search optimization • model checking in practice – tools and tool design – model building and model extraction – challenges Logic Model Checking [2 of 18] 3 a very small example of a multi-threaded system int x, y, r; int *p, *q, *z; int **a; thread_1(void) { p = &x; q = &y; z = &r; } thread_2(void) { r = *p; *p = *q; *q = r; } thread_3(void) { a = &p; *a = z; **a = 12; } Logic Model Checking [2 of 18] /* initialize p, q, and r */ /* swap contents of x and y */ /* access z via a and p */ reads h t s u o n ro 3 asynch shared data g h accessin ents eac ded to m e t a t s 3 are nee s n u r t ccur? s o te n y a n c a n m how corruptio a t a d o n at check th 4 thread interleaving • 3 the number of possible thread interleavings is... 9! 6! 3! ----- · ----- · ---- = 6!.3! 3!.3! 3! 1,680 1,680 possible executions 2 1 placing 3 sets of 3 tokens in 9 slots • • • start are all these executions okay? can we check them all? should we check them all? in classic system testing, how many would normally be checked? Logic Model Checking [2 of 18] 5 simpler still • consider two 2-state automata – representing two asynchronous processes • • one can print an arbitrary number of ‘0’ digits, or stop the other can print an arbitrary number of ‘1’ digits, or stop print ‘0’ stop print ‘1’ stop odel m a d coul w o ssibly h o : p Q h t i eal w d r e ns ? k o i t u c chec e ex infinite how many different combined executions are there? i.e., how many different binary numbers can be printed? how would one test that this system does what we think it does? Logic Model Checking [2 of 18] 6 one cannot, not even in principle, exhaustively test process behavior in a distributed system • problems: – lack of observability in distributed systems • of data access patterns, process scheduling decisions, precise interleaving in time of events that occur in physically distinct systems – lack of controllability • e.g., of process scheduling actions in distinct systems, order of arrival of events, etc. – lack of time • consider 20 possible sources of error, they can occur in 220 possible combinations (220 = 1 million; can you test them all? hint: 1 million seconds is a little over 12 days) • in practice exhaustive testing exhausts the testers long before it exhausts the system… Logic Model Checking [2 of 18] 7 concurrent systems are not just hard to test they are also hard to design (so we need more thorough not less thorough checking) an example: designing foolproof traffic rules (road traffic is one big asynchronous process system with many shared resources) simple rule for traffic circles: “traffic approaching from the right always has priority” Logic Model Checking [2 of 18] 8 an undesirable side-effect of this rule: potential deadlock (also called gridlock or circular waiting) so, okay, that didn’t work Q: would the reverse rule be better? Logic Model Checking [2 of 18] 9 the opposite rule introduces a different set of problems “traffic within the circle always has priority” a different problem: potentially unbounded delay or starvation two questions should come up: how can one predict the consequences of perfectly innocent looking rules like these? how does this get resolved in real-life? Logic Model Checking [2 of 18] 10 distributed algorithms in real-life conflicts ultimately get resolved by human judgment. computers, though, must be able to resolve it with fixed algorithms after-you, no after-you blocking Logic Model Checking [2 of 18] me-first, no me-first blocking two asynchronous processes competing for a shared resource using a fixed algorithm/rule 11 a challenge problem the problem of the Leidsestraat (a busy street in the center of Amsterdam) canal tram tram bridge1 bridge2 street Leidseplein Koningsplein busy two-way traffic of tram-cars through the street 1 track in the street, 2 tracks on bridges the trams pass each other on the bridges priority rule: trams moving to the center (the right) have priority challenge: design a traffic light control algorithm that maximizes throughput of trams and prevents deadlock and starvation hint-1: there are currently no traffic lights in this street Logic Model Checking [2 of 18] 12 no problem? Logic Model Checking [2 of 18] 13 when is a system “correct”? • a system is correct when it meets its requirements “a design without requirements cannot be right or wrong, it can only be surprising” • • therefore, verification must always start with the identification and formalization of all relevant correctness requirements a well-designed system is provably correct – burden of proof: it is best to assume that the system is incorrect until the opposite can be shown – sometimes we have to keep the design simpler than we would like, just to be able to prove its properties – reason: common sense can be misleading, especially in distributed systems design Logic Model Checking [2 of 18] 14 correctness • corollaries: – you cannot prove a system correct in any absolute sense – you can only prove that a system (or a model of a system) does or does not have certain specific properties – it requires human judgment to conclude whether having or not having those properties constitutes ‘correctness’ – getting the properties (requirements) right is as important as getting the (model of the) system right – there is no magic wand, no blind test that could automagically prove an arbitrary given system ‘correct’ Logic Model Checking [2 of 18] 15 types of correctness requirements • some requirements are standard: – a system should not deadlock – no process should be able to starve another – no explicitly stated assertion inside a process should ever fail • others are application specific: – – – – system invariants, process assertions effective progress requirements proper termination general causal and temporal relations on states • e.g., when a request is issued eventually a reply is returned – fairness assumptions, • e.g., about process scheduling – etc. etc. Logic Model Checking [2 of 18] 16 building verification models and selecting correctness requirements tool-based verification often pushes the limits of tractability a good use of selective abstraction is the key to success this is true for any type of proof attempt “it is not reasonable to check the minor details before we have good reason to believe that the major steps of an argument are sound [Polya,How to Solve it, 1945, p. 69] “the point of view is worth 80 IQ points” [Alan Kay] (in logic model checking picking the right point of view, the right abstraction, can be more powerful than the best supercomputer you don’t have) Logic Model Checking [2 of 18] 17 the choice of the model depends on the requirements that must be checked • a good model is always an abstraction of reality – it should have less detail than the artifact being modeled – the level of detail is selected based on its relevance to the correctness requirements – the objective is to gain analytical power by reducing detail • the purpose of a model is to explain and predict – if it can do neither because it is too detailed, it is not a good model • a model is a design aid – it often goes through different versions, describing different aspects of reality, and can slowly become more accurate, without becoming more detailed accuracy != detail Logic Model Checking [2 of 18] 18 an example of a powerful abstraction or not n o i t c a r t s ab model s d i o h t o f g o a e this is purpos e h t n o whether y tel /verify) le e t p a r m t o s c n o s depend t to dem n a e m it t is (i.e., wha Logic Model Checking [2 of 18] 19 which is the better abstraction? bad good good! good! bad! bad! status? status? status? hide what is irrelevant or what should be invisible Logic Model Checking [2 of 18] 20 a telephone subscriber how many states can the process be in? • in some cases, a 1-state automaton is the best conservative abstraction to describe all possible (and some impossible) behaviors of a complex system (e.g. a telephone subscriber) on-hook off-hook digit 0 … Logic Model Checking [2 of 18] digit 9 21 two things we always abstract from in logic model checking • • • a correctness proof that makes no assumptions about the passage of time or about the probability (rather than the possibility) of events is stronger than one that does in distributed systems, logical correctness and real-time performance should be treated as orthogonal concerns Dijkstra’s golden rule: in distributed systems design, one can never make assumptions about the relative speed of execution of asynchronously executing processes (and the same holds for proofs of correctness) real-time Logic Model Checking [2 of 18] probability 22 building verification models • we want to be able to make separate statements about system design and about system requirements • therefore we will need two notations/formalisms – one for specifying behavior (system design) – one for specifying requirements (correctness properties) • the two types of statements combined define a verification model • a model checker can now: – check that the behavior specification (the design) is logically consistent with the requirements specification (the desired properties of the design) – the formalism must be defined in such a way that we can guarantee the decidability of any property we can state for any system we can specify Logic Model Checking [2 of 18] 23 Spin verification models are used to define abstractions of distributed system designs • • the specification language must support all essential aspects of distributed systems software, and discourage the specification of any redundant detail (not bearing on things that are provable) there are 3 basic types of objects in a Spin verification model: – asynchronous processes – global and local data objects – message channels global data process0 process1 message channels local data Logic Model Checking [2 of 18] local data 24 hello world as a “Spin model” these are keywords start s0 ‘main’ is not a keyword print automaton s1 active proctype main() no semi-colon here… stop { a simulation run: printf(“hello world\n”) $$ spin spin hello.pml hello.pml } hello world hello world this is a bit like C 11 process process created created $$ a verification run: $$ spin spin –a –a hello.pml hello.pml $$ gcc gcc –o –o pan pan pan.c pan.c $$ ./pan ./pan ... ... depth depth reached reached 2, 2, errors: errors: 00 $$ Logic Model Checking [2 of 18] 25 a more interesting example: two processes a card reader and a line printer process 1 process 2 ?A ?B ?B ?A !A !B ?A reserve printer device ?B reserve card reader !B !A !A release printer device !B release card reader Logic Model Checking [2 of 18] 26 the corresponding Spin model (don’t worry about the details just yet) $$ cat cat generic.pml generic.pml bool bool printer printer == true; true; bool bool reader reader == true; true; /* /* initially initially both both devices devices */ */ /* /* are are available available */ */ active active [2] [2] proctype proctype user() user() {{ do do :: :: (printer) (printer) -> -> printer printer == false; false; (reader) (reader) -> -> reader reader == false; false; /* /* print print cards cards */ */ printer = true; printer = true; /* /* available available */ */ reader reader == true true :: :: (reader) (reader) -> -> reader reader == false; false; (printer) (printer) -> -> printer printer == false; false; /* print cards */ /* print cards */ reader reader == true; true; printer printer == true true od od }} $$ Logic Model Checking [2 of 18] 27 a simulation of 20 steps $$ spin spin -v -v -u20 -u20 generic.pml generic.pml 0: proc 0: proc -- (:root:) (:root:) creates creates proc proc 11 (user) (user) 1: proc 0 (user) line 6 "generic.pml" 1: proc 0 (user) line 6 "generic.pml" (state (state 2: proc 77 "generic.pml" 2: proc 00 (user) (user) line line "generic.pml" (state (state 3: proc 88 "generic.pml" 3: proc 00 (user) (user) line line "generic.pml" (state (state 4: proc 1 (user) line 6 "generic.pml" (state 4: proc 1 (user) line 6 "generic.pml" (state 5: proc 88 "generic.pml" 5: proc 00 (user) (user) line line "generic.pml" (state (state 6: proc 1 (user) line 13 "generic.pml" (state 6: proc 1 (user) line 13 "generic.pml" (state 7: proc 7: proc 00 (user) (user) line line 10 10 "generic.pml" "generic.pml" (state (state 8: proc 1 (user) line 14 "generic.pml" (state 8: proc 1 (user) line 14 "generic.pml" (state 9: proc 9: proc 11 (user) (user) line line 14 14 "generic.pml" "generic.pml" (state (state 10: proc 10: proc 00 (user) (user) line line 11 11 "generic.pml" "generic.pml" (state (state 11: proc 0 (user) line 19 "generic.pml" (state 11: proc 0 (user) line 19 "generic.pml" (state 12: proc 66 "generic.pml" 12: proc 00 (user) (user) line line "generic.pml" (state (state 13: proc 1 (user) line 16 "generic.pml" (state 13: proc 1 (user) line 16 "generic.pml" (state 14: proc 14: proc 11 (user) (user) line line 17 17 "generic.pml" "generic.pml" (state (state 15: proc 15: proc 11 (user) (user) line line 19 19 "generic.pml" "generic.pml" (state (state 16: proc 1 (user) line 6 "generic.pml" (state 16: proc 1 (user) line 6 "generic.pml" (state 17: proc 17: proc 00 (user) (user) line line 13 13 "generic.pml" "generic.pml" (state (state 18: proc 1 (user) line 13 "generic.pml" (state 18: proc 1 (user) line 13 "generic.pml" (state 19: proc 19: proc 00 (user) (user) line line 14 14 "generic.pml" "generic.pml" (state (state 20: proc 20: proc 11 (user) (user) line line 14 14 "generic.pml" "generic.pml" (state (state 13)[(printer)] 13)[(printer)] 2) 2) [printer [printer == 0] 0] 3) [(reader)] 3) [(reader)] 13)[(reader)] 13)[(reader)] 4) 4) [reader [reader == 0] 0] 8) [reader = 0] 8) [reader = 0] 5) 5) [printer [printer == 1] 1] 9) [(printer)] 9) [(printer)] 10)[printer 10)[printer == 0] 0] 6) 6) [reader [reader == 1] 1] 14)[.(goto)] 14)[.(goto)] 13)[(reader)] 13)[(reader)] 11)[reader 11)[reader == 1] 1] 12)[printer 12)[printer == 1] 1] 14)[.(goto)] 14)[.(goto)] 13)[(reader)] 13)[(reader)] 8) 8) [reader [reader == 0] 0] 8) [reader = 0] 8) [reader = 0] 9) 9) [(printer)] [(printer)] 9) 9) [(printer)] [(printer)] ------------------------depth-limit depth-limit (-u20 (-u20 steps) steps) reached reached #processes: #processes: 22 printer printer == 11 reader reader == 00 20: proc 20: proc 11 (user) (user) line line 14 14 "generic.pml" "generic.pml" (state (state 10) 10) 20: proc 20: proc 00 (user) (user) line line 14 14 "generic.pml" "generic.pml" (state (state 10) 10) 22 processes processes created created $$ Logic Model Checking [2 of 18] 28 a verification (checking a default property: absence of deadlock) $$ spin spin -a -a generic.pml generic.pml $$ gcc –DBFS gcc –DBFS –o –o pan pan pan.c pan.c $$ ./pan ./pan pan: pan: invalid invalid end end state state (at (at depth depth 4) 4) pan: pan: wrote wrote generic.pml.trail generic.pml.trail (Spin (Spin Version Version 4.1.0 4.1.0 --- 19 19 November November 2003) 2003) Warning: Search not completed Warning: Search not completed ++ Using Using Breadth-First Breadth-First Search Search ++ Partial Order Reduction Partial Order Reduction Full Full statespace statespace search search for: for: never claim never claim assertion assertion violations violations cycle checks cycle checks DSAFETY) DSAFETY) invalid invalid end end states states -++ -- (none (none specified) specified) (disabled (disabled by by -- ++ State-vector State-vector 20 20 byte, byte, depth depth reached reached 4, 4, errors: errors: 11 44 44 states, states, stored stored 44 nominal 44 nominal states states (stored-atomic) (stored-atomic) 16 16 states, states, matched matched 60 60 transitions transitions (= (= stored+matched) stored+matched) 00 atomic atomic steps steps hash hash conflicts: conflicts: 00 (resolved) (resolved) (max size 2^18 states) (max size 2^18 states) 1.253 1.253 $$ spin’s euphemism for deadlock stopped at first error found memory memory usage usage (Mbyte) (Mbyte) Logic Model Checking [2 of 18] 29 inspection of the error trail $$ spin spin -t -t -v -v generic.pml generic.pml 1: proc 77 1: proc 11 (user) (user) line line 2: proc 77 2: proc 11 (user) (user) line line 3: proc 3: proc 00 (user) (user) line line 13 13 4: proc 4: proc 00 (user) (user) line line 13 13 spin: spin: trail trail ends ends after after 44 steps steps #processes: 2 #processes: 2 printer printer == 00 reader reader == 00 4: proc 88 4: proc 11 (user) (user) line line 4: proc 4: proc 00 (user) (user) line line 14 14 22 processes processes created created $$ "generic.pml" "generic.pml" "generic.pml" "generic.pml" "generic.pml" "generic.pml" "generic.pml" "generic.pml" (state (state (state (state (state (state (state (state [(printer)] [(printer)] [printer [printer == 0] 0] [(reader)] [(reader)] [reader [reader == 0] 0] "generic.pml" "generic.pml" (state (state 3) 3) "generic.pml" "generic.pml" (state (state 9) 9) process 1 process 2 ?A ?B ?B 1) 1) 2) 2) 7) 7) 8) 8) printer == 0 && reader == 0 ?A deadlock Logic Model Checking [2 of 18] 30 the Spin gui – getting fancy Logic Model Checking [2 of 18] 31
© Copyright 2026 Paperzz