More on Verification and Model Checking Wednesday Oct 07, 2015 Philipp Rümmer Uppsala University Philipp.Ruemmer@it.uu.se 1/60
Course fair! 2/60
Exam st October 21, 8:00 13:00 If you want to participate, register now! (You also need to bring ID card/passport to the exam) 3/60
Outline Timed automata vs. software Four general model checking approaches Explicit-state Symbolic Bounded Abstraction-based 4/60
Verification also here? 6/60
Software model checking Bounded model checking (BMC) Geared towards bug finding Tools like: CBMC, LLBMC, Full model checking Primarily used to show absence of bugs Tools like: Spin, Blast, CPAChecker, SatAbs, Eldarica, SeaHorn, Similar techniques as in Uppaal Annual competition: SV-COMP 7/60
Some examples 8/60
Definition of properties assert Check whether condition holds; otherwise, stop program execution with an error Comparable to a post-condition assume Checks whether condition holds; otherwise, suspend further program execution Comparable to a pre-condition 9/60
Web interfaces CBMC http://logicrunch.it.uu.se:4096/~wv/cbmc/ Eldarica http://logicrunch.it.uu.se:4096/~wv/eldarica/ 10/60
Analysis of Timed Automata vs. Code Representing one using the other? 11/60
Control-flow graphs (CFGs) int mult(int a, int b){ int z = 0; while ( a!= 0) { if ( a % 2!= 0) { z = z+b; } a = a /2; b = b *2; } return z; } Graphical representation of code: Nodes are control-flow locations + statements Edges denote transitions + guards 12/60
As automaton Represent every node as an automaton state Statements are turned into updates 13/60
Automata as code? void main() { int i = 0; wait : goto increase; increase : if (i < 5) { i = i + 1; goto wait; } else { goto done; } done : ; } 14/60
Additional aspects Communication/synchronisation Atomicity Guards + updates are atomic Time Non-determinism Sometimes, multiple transitions might be possible Guards/partiality For analysis, considered as assume In general, not executable 15/60
Additional features of software Structure Datatypes/structures Functions, classes, modules Pointers, heap, arrays Large state space (But normally no time) 16/60
Global view: Transition systems (TS) Tuple State space Initial states State transitions Notion capturing various types of systems Related concept: Kripke structures 17/60
Example 18/60
Finite automaton as TS Simply leave out labels to obtain TS 19/60
Automaton with time/data 20/60
Software program as TS 21/60
Safety of transition system Identify set System path with of error states is safe if there is no and Safety = (un)reachability in graph Is any error state reachable from an initial state? 22/60
Example 23/60
The state space explosion problem The size of set grows very rapidly Exponentially in number of variables Exponentially in number of threads/processes Sometimes, is even considered infinite (e.g., time is unbounded) Checking reachability can be challenging (or undecidable) 24/60
Method 1: Explicit-state model checking Explicitly construct graph Check reachability of error states Example tool: Spin, Java Path Finder Problem: complexity linear in size of TS, only works for very small TS (millions/billions of states) 25/60
Side note: CTL properties Reachability covers the cases A[], E<> How can we check A<>, E[]? (for finite TS) For E[] p: Search for cycles on which p holds in every state Determine states from which such cycle are reachable, only following p states 26/60
Method 2: Symbolic model checking Represent graph symbolically; normally using Binary Decision Diagrams (BDDs) Check reachability of error states by fixed-point computation Example tool: SMV 27/60
Binary Decision Diagrams Data structure to represent Boolean functions Often concise in memory Canonical representation Boolean operations on BDDs (&&,, etc) can be executed efficiently (usually in polynomial time) 28/60
Binary Decision Diagrams (2) 29/60
Binary Decision Diagrams (3) Sets can be represented by their characteristic function If elements of are encoded as sequences of, then is a Boolean function, can be represented as BDD 30/60
Binary Decision Diagrams (4) For transition systems Represent variables using vector of Boolean can then be represented using BDDs Safety + CTL properties can be checked by fixed-point computation 31/60
Method 2: Symbolic model checking Big success in the 90s: Suddenly able to analyse real hardware implementations (processors, memory, etc.) J.R. Burch, E.M. Clarke, K.L. McMillan. D.L. Dill, L.J. Hwang: Symbolic model checking: 10^20 states and beyond. 32/60
Method 2: Symbolic model checking 10^20 states is still way too few E.g., software program with ten 32bit integer variables has states 33/60
Method 3: Bounded model checking Idea: search for bugs in programs/systems up to some depth; but otherwise reason fully precisely Tailored to showing reachability, not so much unreachability Today, one of the most successful techniques for hardware analysis BMC Problem Decide whether an error can be reached within the first k execution steps of a program/system. 34/60
35/60
Monolithic BMC Transition system Finite state space Initial states Transition relation E.g., repres. by vectors of Booleans Errors 36/60
Monolithic BMC (2) If the formula can be solved, then represent a path visiting an error state Various solvers can be applied: Linear/mixed integer programming SAT/SMT solving Convex optimisation 37/60
Monolithic BMC (3) Mainly works well for hardware For software, formula contains a lot of redundancy Better to unwind program guided by control structure Example tool: CBMC 38/60
BMC: straight-line programs int x, y; x = x * x; y = x + 1; assert(y > 0); E.g., check using the constraint solver Z3: (set-option :pp.bv-literals false) (declare-const x0 (_ BitVec 32)) (declare-const y0 (_ BitVec 32)) (declare-const x1 (_ BitVec 32)) (declare-const y1 (_ BitVec 32)) (assert (= x1 (bvmul x0 x0))) (assert (= y1 (bvadd x1 (_ bv1 32)))) (assert (not (bvsgt y1 (_ bv0 32)))) (check-sat) (get-model) Signed comparison 39/60
BMC: conditional branching int x, y; if (x > 0) y = x; else y = -x; assert(y >= 0); (set-option :pp.bv-literals false) (declare-const (declare-const (declare-const (declare-const (declare-const (declare-const (assert (assert (assert (assert x0 y0 y1a y1b y2 b (_ BitVec (_ BitVec (_ BitVec (_ BitVec (_ BitVec Bool) 32)) 32)) 32)) 32)) 32)) (= b (bvsgt x0 (_ bv0 32)))) (=> b (= y1a x0))) (=> (not b) (= y1b (bvneg x0)))) (= y2 (ite b y1a y1b))) (assert (not (bvsge y2 (_ bv0 32)))) (check-sat) (get-model) 40/60
Further features Data-structures, heap, pointers Concurrency Can be represented using scalar variables, since only finitely many variables/heap locations can be used in k execution steps Systematically explore all possible interleavings of threads Also applicable to timed automata, and other kinds of systems 41/60
Method 4: Abstraction-based MC Idea: instead of analysing full model/code, compute and analyse a small abstraction of it Refine if the abstraction is too coarse In particular successful for software Example tools: CPAChecker, SatAbs, SLAM, Eldarica, SeaHorn 42/60
Example Abstraction has introduced a spurious counterexample 43/60
Example In this abstraction no error states are reachable! 44/60
Existential abstraction A transition system is an existential abstraction of with respect to if 1. 2. ( is a homomorphism) 45/60
Safety through abstraction If is an existential abstraction of with respect to and in none of the states is reachable, then is safe w.r.t. (The same does not hold for all CTL properties; but other forms of abstraction exist...) 46/60
Abstraction refinement 47/60
Predicate abstraction In software, abstraction is usually defined through a set of predicates 48/60
CEGAR Counterexample-guided abstraction refinement 49/60
CEGAR (2) In each refinement step, one (or multiple) abstract states are split The procedure never gives a wrong answer; but might not terminate for infinite-state systems Termination guaranteed for finite-state systems 50/60
Abstraction-based MC In many cases, abstraction-based model checking can also analyse infinite-state systems Programs with unbounded heap Infinite datatypes (e.g., true integers) Unbounded/infinite number of threads 51/60
What is Uppaal using? For automata locations, data variables: Explicit-state model checking For time and clocks: Abstraction-based model checking ( regions and zones ) 52/60
Case study: Fischer protocol Simple mutual exclusion protocol; only needs one shared variable lock Assumptions: Time bound A known after which writes to shared variable are visible to all threads Every process has an id (> 0), and a timer Popular model checking benchmark 53/60
Fischer protocol as code Every thread executes the following code: loop wait until lock = 0; set lock to process id; // visible after <=A units wait for a delay >= B > A; if lock = process id enter critical section end 54/60
Case study: Fischer protocol (2) Safety property: no two processes can be in cs at the same time 55/60
Verifiable with any number of processes? 56/60
Fischer as parameterised system Infinite family of transition systems One instance per number of threads Some model checkers can verify correctness for all instances at once E.g., Eldarica Idea: analyse system assuming infinitely many threads using abstraction; this subsumes all cases with finitely many threads 57/60
In C/Eldarica syntax int lock = 0; thread[tid] Proc { clock C; assume(tid > 0); while (1) { atomic { assume(lock == 0); C = 0; } within (C <= 1) lock = tid; // within = time inv. C = 0; assume(c > 1); if (lock == tid) { // critical section assert(lock == tid); lock = 0; } } } // delay >1 time unit 58/60
Conclusions Four model checking approaches Explicit-state Symbolic Bounded Abstraction-based 59/60
Further reading Orna Grumberg: Model Checking: From BDDs to Interpolation www.cs.technion.ac.il/users/orna/markt-2011.pdf Daniel Kroening: Predicate Abstraction, A Tutorial fm.csl.sri.com/ssft12/predabs-ssft12.pdf 60/60