Presentation is loading. Please wait.

Presentation is loading. Please wait.

Software Model Checking with SLAM Thomas Ball Testing, Verification and Measurement Sriram K. Rajamani Software Productivity Tools Microsoft Research

Similar presentations


Presentation on theme: "Software Model Checking with SLAM Thomas Ball Testing, Verification and Measurement Sriram K. Rajamani Software Productivity Tools Microsoft Research"— Presentation transcript:

1 Software Model Checking with SLAM Thomas Ball Testing, Verification and Measurement Sriram K. Rajamani Software Productivity Tools Microsoft Research http://research.microsoft.com/slam/

2 People behind SLAM Summer interns –Sagar Chaki, Todd Millstein, Rupak Majumdar (2000) –Satyaki Das, Wes Weimer, Robby (2001) –Jakob Lichtenberg, Mayur Naik (2002) Visitors –Giorgio Delzanno, Andreas Podelski, Stefan Schwoon Windows Partners –Byron Cook, Vladimir Levin, Abdullah Ustuner

3 Outline Part I: Overview (30 min) –overview of SLAM process –demonstration (Static Driver Verifier) –lessons learned Part II: Basic SLAM (1 hour) –foundations –basic algorithms (no pointers) Part III: Advanced Topics (30 min) –pointers + procedures –imprecision in aliasing and mod analysis

4 Part I: Overview of SLAM

5 What is SLAM? SLAM is a software model checking project at Microsoft Research –Goal: Check C programs (system software) against safety properties using model checking –Application domain: device drivers Starting to be used internally inside Windows –Working on making this into a product

6 Source Code Testing Development Precise API Usage Rules (SLIC) Software Model Checking Read for understanding New API rules Drive testing tools Defects 100% path coverage Rules Static Driver Verifier

7 SLAM – Software Model Checking SLAM innovations –boolean programs: a new model for software –model creation (c2bp) –model checking (bebop) –model refinement (newton) SLAM toolkit –built on MSR program analysis infrastructure

8 SLIC Finite state language for stating rules –monitors behavior of C code –temporal safety properties (security automata) –familiar C syntax Suitable for expressing control-dominated properties –e.g. proper sequence of events –can encode data values inside state

9 State Machine for Locking UnlockedLocked Error Rel Acq Rel state { enum {Locked,Unlocked} s = Unlocked; } KeAcquireSpinLock.entry { if (s==Locked) abort; else s = Locked; } KeReleaseSpinLock.entry { if (s==Unlocked) abort; else s = Unlocked; } Locking Rule in SLIC

10 prog. P’ prog. P SLIC rule The SLAM Process boolean program path predicates slic c2bp bebop newton

11 do { KeAcquireSpinLock(); nPacketsOld = nPackets; if(request){ request = request->Next; KeReleaseSpinLock(); nPackets++; } } while (nPackets != nPacketsOld); KeReleaseSpinLock(); Example Does this code obey the locking rule?

12 do { KeAcquireSpinLock(); if(*){ KeReleaseSpinLock(); } } while (*); KeReleaseSpinLock(); Example Model checking boolean program (bebop) U L L L L U L U U U E

13 do { KeAcquireSpinLock(); nPacketsOld = nPackets; if(request){ request = request->Next; KeReleaseSpinLock(); nPackets++; } } while (nPackets != nPacketsOld); KeReleaseSpinLock(); Example Is error path feasible in C program? (newton) U L L L L U L U U U E

14 do { KeAcquireSpinLock(); nPacketsOld = nPackets; b = true; if(request){ request = request->Next; KeReleaseSpinLock(); nPackets++; b = b ? false : *; } } while (nPackets != nPacketsOld); !b KeReleaseSpinLock(); Example Add new predicate to boolean program (c2bp) b : (nPacketsOld == nPackets) U L L L L U L U U U E

15 do { KeAcquireSpinLock(); b = true; if(*){ KeReleaseSpinLock(); b = b ? false : *; } } while ( !b ); KeReleaseSpinLock(); b b b b Example Model checking refined boolean program (bebop) b : (nPacketsOld == nPackets) U L L L L U L U U U E b b !b

16 Example do { KeAcquireSpinLock(); b = true; if(*){ KeReleaseSpinLock(); b = b ? false : *; } } while ( !b ); KeReleaseSpinLock(); b : (nPacketsOld == nPackets) b b b b U L L L L U L U U b b !b Model checking refined boolean program (bebop)

17 Observations about SLAM Automatic discovery of invariants –driven by property and a finite set of (false) execution paths –predicates are not invariants, but observations –abstraction + model checking computes inductive invariants (boolean combinations of observations) A hybrid dynamic/static analysis –newton executes path through C code symbolically –c2bp+bebop explore all paths through abstraction A new form of program slicing –program code and data not relevant to property are dropped –non-determinism allows slices to have more behaviors

18 Part I: Demo Static Driver Verifier results

19 Part I: Lessons Learned

20 SLAM Boolean program model has proved itself Successful for domain of device drivers –control-dominated safety properties –few boolean variables needed to do proof or find real counterexamples Counterexample-driven refinement –terminates in practice –incompleteness of theorem prover not an issue

21 What is hard? Abstracting –from a language with pointers (C) –to one without pointers (boolean programs) All side effects need to be modeled by copying (as in dataflow) Open environment problem

22 What stayed fixed? Boolean program model Basic tool flow Repercussions: –newton has to copy between scopes –c2bp has to model side-effects by value-result –finite depth precision on the heap is all boolean programs can do

23 What changed? Interface between newton and c2bp We now use predicates for doing more things refine alias precision via aliasing predicates newton helps resolve pointer aliasing imprecision in c2bp

24 Scaling SLAM Largest driver we have processed has ~60K lines of code Largest abstractions we have analyzed have several hundred boolean variables Routinely get results after 20-30 iterations Out of 672 runs we do daily, 607 terminate within 20 minutes

25 Scale and SLAM components Out of 67 runs that time out, tools that take longest time: –bebop: 50, c2bp: 10, newton: 5, constrain: 2 C2bp: –fast predicate abstraction (fastF) and incremental predicate abstraction (constrain) –re-use across iterations Newton: –biggest problems are due to scope-copying Bebop: –biggest issue is no re-use across iterations –solution in the works

26 SLAM Status 2000-2001 –foundations, algorithms, prototyping –papers in CAV, PLDI, POPL, SPIN, TACAS March 2002 –Bill Gates review May 2002 –Windows committed to hire two people with model checking background to support Static Driver Verifier (SLAM+driver rules) July 2002 –running SLAM on 100+ drivers, 20+ properties September 3, 2002 –made initial release of SDV to Windows (friends and family) April 1, 2003 –made wide release of SDV to Windows (any internal driver developer)

27 Part II: Basic SLAM

28 C- Types  ::= void | bool | int | ref  Expressionse::=c | x | e 1 op e 2 | &x | *x LExpression l ::= x | *x Declarationd::=  x 1,x 2,…,x n Statementss::=skip | goto L 1,L 2 …L n | L: s | assume(e) | l = e | l = f (e 1,e 2,…,e n ) |return x |s 1 ; s 2 ;… ; s n Procedures p ::=  f (x 1 :  1,x 2 :  2,…,x n :  n ) Programg ::= d 1 d 2 … d n p 1 p 2 … p n

29 C-- Types  ::= void | bool | int Expressionse::=c | x | e 1 op e 2 LExpression l ::= x Declarationd::=  x 1,x 2,…,x n Statementss::=skip | goto L 1,L 2 …L n | L: s | assume(e) | l = e |f (e 1,e 2,…,e n ) |return |s 1 ; s 2 ;… ; s n Procedures p ::= f (x 1 :  1,x 2 :  2,…,x n :  n ) Programg ::= d 1 d 2 … d n p 1 p 2 … p n

30 BP Types  ::= void | bool Expressionse::=c | x | e 1 op e 2 LExpression l ::= x Declarationd::=  x 1,x 2,…,x n Statementss::=skip | goto L 1,L 2 …L n | L: s | assume(e) | l = e |f (e 1,e 2,…,e n ) |return |s 1 ; s 2 ;… ; s n Procedures p ::= f (x 1 :  1,x 2 :  2,…,x n :  n ) Programg ::= d 1 d 2 … d n p 1 p 2 … p n

31 Syntactic sugar if (e) { S1; } else { S2; } S3; goto L1, L2; L1: assume(e); S1; goto L3; L2: assume(!e); S2; goto L3; L3: S3;

32 Example, in C void cmp (int a, int b) { if (a == b) g = 0; else g = 1; } int g; main(int x, int y){ cmp(x, y); if (!g) { if (x != y) assert(0); }

33 void cmp(int a, int b) { goto L1, L2; L1: assume(a==b); g = 0; return; L2: assume(a!=b); g = 1; return; } int g; main(int x, int y){ cmp(x, y); assume(!g); assume(x != y) assert(0); } Example, in C--

34 prog. P’ prog. P SLIC rule The SLAM Process boolean program path predicates slic c2bp bebop newton

35 c2bp: Predicate Abstraction for C Programs Given P : a C program F = {e 1,...,e n } –each e i a pure boolean expression –each e i represents set of states for which e i is true Produce a boolean program B(P,F) same control-flow structure as P boolean vars {b 1,...,b n } to match {e 1,...,e n } properties true of B(P,F) are true of P

36 Assumptions Given P : a C program F = {e 1,...,e n } –each e i a pure boolean expression –each e i represents set of states for which e i is true Assume: each e i uses either: –only globals (global predicate) –local variables from some procedure (local predicate for that procedure) Mixed predicates: –predicates using both local variables and global variables –complicate “return” processing –covered in advanced topics

37 C2bp Algorithm Performs modular abstraction –abstracts each procedure in isolation Within each procedure, abstracts each statement in isolation –no control-flow analysis –no need for loop invariants

38 void cmp (int a, int b) { goto L1, L2 L1: assume(a==b); g = 0; return; L2: assume(a!=b); g = 1; return; } int g; main(int x, int y){ cmp(x, y); assume(!g); assume(x != y) assert(0); } Preds: {x==y} {g==0} {a==b}

39 void cmp (int a, int b) { goto L1, L2 L1: assume(a==b); g = 0; return; L2: assume(a!=b); g = 1; return; } int g; main(int x, int y){ cmp(x, y); assume(!g); assume(x != y) assert(0); } decl {g==0} ; main( {x==y} ) { } void cmp ( {a==b} ) { } Preds: {x==y} {g==0} {a==b}

40 void equal (int a, int b) { goto L1, L2 L1: assume(a==b); g = 0; return; L2: assume(a!=b); g = 1; return; } int g; main(int x, int y){ cmp(x, y); assume(!g); assume(x != y) assert(0); } decl {g==0} ; main( {x==y} ) { cmp( {x==y} ); assume( {g==0} ); assume( !{x==y} ); assert(0); } void cmp ( {a==b} ) { goto L1, L2; L1: assume( {a==b} ); {g==0} = T; return; L2: assume( !{a==b} ); {g==0} = F; return; } Preds: {x==y} {g==0} {a==b}

41 C-- Types  ::= void | bool | int Expressionse::=c | x | e 1 op e 2 LExpression l ::= x Declarationd::=  x 1,x 2,…,x n Statementss::=skip | goto L 1,L 2 …L n | L: s | assume(e) | l = e | f (e 1,e 2,…,e n ) | return | s 1 ; s 2 ;… ; s n Procedures p ::= f (x 1 :  1,x 2 :  2,…,x n :  n ) Programg ::= d 1 d 2 … d n p 1 p 2 … p n

42 Statement y=y+1 and F={ y<4, y<5 } –{y<4}, {y<5} = ((!{y<5} || !{y<4}) ? F : *), {y<4} ; WP(x=e,Q) = Q[x -> e] WP(y=y+1, y<5)= (y y+1] = (y+1<5) = (y<4) Abstracting Assigns via WP

43 WP Problem WP(s, e i ) not always expressible via { e 1,...,e n } Example –F = { x==0, x==1, x<5 } –WP( x=x+1, x<5 ) = x<4 –Best possible: x==0 || x==1

44 Abstracting Expressions via F F = { e 1,...,e n } Implies F (e) –best boolean function over F that implies e ImpliedBy F (e) –best boolean function over F implied by e –ImpliedBy F (e) = !Implies F (!e)

45 Implies F (e) and ImpliedBy F (e) e Implies F (e) ImpliedBy F (e)

46 Computing Implies F (e) minterm m = d 1 &&... && d n –where d i = e i or d i = !e i Implies F (e) –disjunction of all minterms that imply e Naïve approach –generate all 2 n possible minterms –for each minterm m, use decision procedure to check validity of each implication m  e Many optimizations possible

47 Abstracting Assignments if Implies F (WP(s, e i )) is true before s then –e i is true after s if Implies F (WP(s, !e i )) is true before s then –e i is false after s {e i } = Implies F (WP(s, e i )) ?true : Implies F (WP(s, !e i )) ? false : *;

48 Assignment Example Statement in P: Predicates in E: y = y+1; {x==y} Weakest Precondition: WP(y=y+1, x==y) = x==y+1 Implies F ( x==y+1 ) = false Implies F ( x!=y+1 ) = x==y Abstraction of assignment in B: {x==y} = {x==y} ? false : *;

49 Absracting Assumes WP( assume(e), Q) = e  Q assume(e) is abstracted to: assume( ImpliedBy F (e) ) Example: F = {x==2, x<5} assume(x < 2) is abstracted to: assume( {x<5} && !{x==2} )

50 Abstracting Procedures Each predicate in F is annotated as being either global or local to a particular procedure Procedures abstracted in two passes: –a signature is produced for each procedure in isolation –procedure calls are abstracted given the callees’ signatures

51 Abstracting a procedure call Procedure call –a sequence of assignments from actuals to formals –see assignment abstraction Procedure return –NOP for C-- with assumption that all predicates mention either only globals or only locals –with pointers and with mixed predicates: Most complicated part of c2bp Covered in the advanced topics section

52 void cmp (int a, int b) { Goto L1, L2 L1: assume(a==b); g = 0; return; L2: assume(a!=b); g = 1; return; } int g; main(int x, int y){ cmp(x, y); assume(!g); assume(x != y) assert(0); } decl {g==0} ; main( {x==y} ) { cmp( {x==y} ); assume( {g==0} ); assume( !{x==y} ); assert(0); } void cmp ( {a==b} ) { Goto L1, L2 L1: assume( {a==b} ); {g==0} = T; return; L2: assume( !{a==b} ); {g==0} = F; return; } {x==y} {g==0} {a==b}

53 Precision For program P and E = {e 1,...,e n }, there exist two “ideal” abstractions: –Boolean(P,E) : most precise abstraction –Cartesian(P,E) : less precise abtraction, where each boolean variable is updated independently –[See Ball-Podelski-Rajamani, TACAS 00] Theory: –with an “ideal” theorem prover, c2bp can compute Cartesian(P,E) Practice: –c2bp computes a less precise abstraction than Cartesian(P,E) –we use Das/Dill’s technique to incrementally improve precision –with an “ideal” theorem prover, the combination of c2bp + Das/Dill can compute Boolean(P,E)

54 prog. P’ prog. P SLIC rule The SLAM Process boolean program path predicates slic c2bp bebop newton

55 Bebop Model checker for boolean programs Based on CFL reachability –[Sharir-Pnueli 81] [Reps-Sagiv-Horwitz 95] Iterative addition of edges to graph –“path edges”:  –“summary edges”: 

56 Symbolic CFL reachability  Partition path edges by their “target”  PE(v) = { |  }  What is for boolean programs?  A bit-vector!  What is PE(v)?  A set of bit-vectors  Use a BDD (attached to v) to represent PE(v)

57 BDDs Canonical representation of –boolean functions –set of (fixed-length) bitvectors –binary relations over finite domains Efficient algorithms for common dataflow operations –transfer function –join/meet –subsumption test void cmp ( e2 ) { [5]Goto L1, L2 [6]L1: assume( e2 ); [7] gz = T; goto L3; [8]L2: assume( !e2 ); [9]gz = F; goto L3 [10] L3: return; } e2=e2’ & gz’=e2’ BDD at line [10] of cmp: Read: “cmp leaves e2 unchanged and sets gz to have the same final value as e2”

58 gz=gz’& e=e’ e=e’& gz’=e’ e=e’ & gz’=1 & e’=1 gz=gz’& e2=e2’ gz=gz’& e2=e2’& e2’=T e2=e2’& gz’=e2’ decl gz ; main( e ) { [1] equal( e ); [2] assume( gz ); [3] assume( !e ); [4] assert(F); } void cmp ( e2 ) { [5]Goto L1, L2 [6]L1: assume( e2 ); [7] gz = T; goto L3; [8]L2: assume( !e2 ); [9]gz = F; goto L3 [10] L3: return; } gz=gz’& e2=e2’& e2’=F e2=e2’& e2’=T & gz’=T e2=e2’& e2’=F & gz’=F e2=e

59 Bebop: summary  Explicit representation of CFG  Implicit representation of path edges and summary edges  Generation of hierarchical error traces  Complexity: O(E * 2 O(N) )  E is the size of the CFG  N is the max. number of variables in scope

60 prog. P’ prog. P SLIC rule The SLAM Process boolean program path predicates slic c2bp bebop newton

61 Newton Given an error path p in boolean program B –is p a feasible path of the corresponding C program? Yes: found an error No: find predicates that explain the infeasibility –uses the same interfaces to the theorem provers as c2bp.

62 Newton Execute path symbolically Check conditions for inconsistency using theorem prover (satisfiability) After detecting inconsistency: –minimize inconsistent conditions –traverse dependencies –obtain predicates

63 Symbolic simulation for C-- Domains –variables: names in the program –values: constants + symbols State of the simulator has 3 components: –store: map from variables to values –conditions: predicates over symbols –history: past valuations of the store

64 Symbolic simulation Algorithm Input: path p For each statement s in p do match s with Assign(x,e): let val = Eval(e) in if (Store[x]) is defined then History[x] := History[x]  Store[x] Store[x] := val Assume(e): let val = Eval(e) in Cond := Cond and val let result = CheckConsistency(Cond) in if (result == “inconsistent”) then GenerateInconsistentPredicates() End Say “Path p is feasible”

65 Symbolic Simulation: Caveats Procedure calls –add a stack to the simulator –push and pop stack frames on calls and returns –implement mappings to keep values “in scope” at calls and returns Dependencies –for each condition or store, keep track of which values where used to generate this value –traverse dependency during predicate generation

66 void cmp (int a, int b) { Goto L1, L2 L1: assume(a==b); g = 0; return; L2: assume(a!=b); g = 1; return; } int g; main(int x, int y){ cmp(x, y); assume(!g); assume(x != y) assert(0); }

67 void cmp (int a, int b) { Goto L1, L2 L1: assume(a==b); g = 0; return; L2: assume(a!=b); g = 1; return; } int g; main(int x, int y){ cmp(x, y); assume(!g); assume(x != y) assert(0); } Global: main: (1)x: X (2)y: Y Conditions :

68 void cmp (int a, int b) { Goto L1, L2 L1: assume(a==b); g = 0; return; L2: assume(a!=b); g = 1; return; } int g; main(int x, int y){ cmp(x, y); assume(!g); assume(x != y) assert(0); } Global: main: (1)x: X (2)y: Y cmp : (3)a: A (4)b: B Conditions : Map : X  A Y  B

69 void cmp (int a, int b) { Goto L1, L2 L1: assume(a==b); g = 0; return; L2: assume(a!=b); g = 1; return; } int g; main(int x, int y){ cmp(x, y); assume(!g); assume(x != y) assert(0); } Global: (6) g: 0 main: (1)x: X (2)y: Y cmp : (3)a: A (4)b: B Conditions : (5)(A == B) [3, 4] Map : X  A Y  B

70 void cmp (int a, int b) { Goto L1, L2 L1: assume(a==b); g = 0; return; L2: assume(a!=b); g = 1; return; } int g; main(int x, int y){ cmp(x, y); assume(!g); assume(x != y) assert(0); } Global: (6) g: 0 main: (1)x: X (2)y: Y cmp : (3)a: A (4)b: B Conditions : (5)(A == B) [3, 4] (6)(X == Y) [5] Map : X  A Y  B

71 void cmp (int a, int b) { Goto L1, L2 L1: assume(a==b); g = 0; return; L2: assume(a!=b); g = 1; return; } int g; main(int x, int y){ cmp(x, y); assume(!g); assume(x != y) assert(0); } Global: (6) g: 0 main: (1)x: X (2)y: Y cmp : (3)a: A (4)b: B Conditions : (5)(A == B) [3, 4] (6)(X == Y) [5] (7) (X != Y) [1, 2]

72 void cmp (int a, int b) { Goto L1, L2 L1: assume(a==b); g = 0; return; L2: assume(a!=b); g = 1; return; } int g; main(int x, int y){ cmp(x, y); assume(!g); assume(x != y) assert(0); } Global: (6) g: 0 main: (1)x: X (2)y: Y cmp : (3)a: A (4)b: B Conditions : (5)(A == B) [3, 4] (6)(X == Y) [5] (7) (X != Y) [1, 2] Contradictory!

73 void cmp (int a, int b) { Goto L1, L2 L1: assume(a==b); g = 0; return; L2: assume(a!=b); g = 1; return; } int g; main(int x, int y){ cmp(x, y); assume(!g); assume(x != y) assert(0); } Global: (6) g: 0 main: (1)x: X (2)y: Y cmp : (3)a: A (4)b: B Conditions : (5)(A == B) [3, 4] (6)(X == Y) [5] (7) (X != Y) [1, 2] Contradictory!

74 void cmp (int a, int b) { Goto L1, L2 L1: assume(a==b); g = 0; return; L2: assume(a!=b); g = 1; return; } int g; main(int x, int y){ cmp(x, y); assume(!g); assume(x != y) assert(0); } Predicates after simplification: { x == y, a == b }

75 Part III: Advanced Topics

76 Types  ::= void | bool | int | ref  Expressionse::=c | x | e 1 op e 2 | &x | *x LExpression l ::= x | *x Declarationd::=  x 1,x 2,…,x n Statementss::=skip | goto L 1,L 2 …L n | L: s | assume(e) | l = e | l = f (e 1,e 2,…,e n ) |return x |s 1 ; s 2 ;… ; s n Procedures p ::=  f (x 1 :  1,x 2 :  2,…,x n :  n ) Programg ::= d 1 d 2 … d n p 1 p 2 … p n C-

77 Two Problems Extending SLAM tools for pointers Dealing with imprecision of alias analysis

78 Pointers and SLAM With pointers, C supports call by reference –Strictly speaking, C supports only call by value –With pointers and the address-of operator, one can simulate call-by-reference Boolean programs support only call-by-value-result –SLAM mimics call-by-reference with call-by-value-result Extra complications: –address operator (&) in C –multiple levels of pointer dereference in C

79 What changes with pointers? C2bp –abstracting assignments –abstracting procedure returns Newton –simulation needs to handle pointer accesses –need to copy local heap across scopes to match Bebop’s semantics –need to refine imprecise alias analysis using predicates Bebop –remains unchanged!

80 Assignments + Pointers Weakest Precondition: WP( *p=3, x==5 ) = x==5 What if *p and x alias? We use Das’s pointer analysis [PLDI 2000] to prune disjuncts representing infeasible alias scenarios. Correct Weakest Precondition: (p==&x and 3==5) or (p!=&x and x==5) Statement in P:Predicates in E: *p = 3 {x==5}

81 Abstracting Procedure Return Need to account for –lhs of procedure call –mixed predicates –side-effects of procedure Boolean programs support only call-by- value-result –C2bp models all side-effects using return processing

82 Abstracting Procedure Returns Let a be an actual at call-site P(…) –pre(a) = the value of a before transition to P Let f be a formal of a procedure P –pre(f) = the value of f upon entry to P

83 int R (int f) { int r = f+1; f = 0; return r; } WP(x=r, x==2) = r==2 Q() { int x = 1; x = R(x) } pre(f) == pre(x) x = r {x==1} {x==2} {f==pre(f)} {r==pre(f)+1} predicatecall/return relationcall/return assign {x==2} = s & {x==1}; } bool R ( {f==pre(f)} ) { {r==pre(f)+1} = {f==pre(f)}; {f==pre(f)} = *; return {r==pre(f)+1}; } WP(f=x, f==pre(f) ) = x==pre(f) f = x x==pre(f) is true at the call to R pre(f)==pre(x) and pre(x)==1 and r==pre(f)+1 implies r==2 Q() { {x==1},{x==2} = T,F; s = R(T); {x==1}s

84 {x==1}, {x==2} = *, s & {x==1}; } int R (int f) { int r = f+1; f = 0; return r; } WP(x=r, x==2) = r==2 Q() { int x = 1; x = R(x) } {x==1} {x==2} {f==pre(f)} {r==pre(f)+1} predicatecall/return relationcall/return assign bool R ( {f==pre(f)} ) { {r==pre(f)+1} = {f==pre(f)}; {f==pre(f)} = *; return {r==pre(f)+1}; } WP(f=x, f==pre(f) ) = x==pre(f) x==pre(f) is true at the call to R pre(f)==pre(x) and pre(x)==1 and r==pre(f)+1 implies r==2 Q() { {x==1},{x==2} = T,F; s = R(T); {x==1}s f = x x = r pre(f) == pre(x)

85 Extending Pre-states Suppose formal parameter is a pointer –eg. P(int *f) pre( *f ) –value of *f upon entry to P –can’t change during P * pre( f ) –value of dereference of pre( f ) –can change during P

86 int R (int *a) { *a = *a+1; } Q() { int x = 1; R(&x); } pre(a) = &x {x==1} {x==2} predicatecall/return relationcall/return assign {x==2} = s & {x==1}; } bool R ( {a==pre(a)}, {*pre(a)==pre(*a)} ) { {*pre(a)==pre(*a)+1} = {a==pre(a)} & {*pre(a)==pre(*a)} ; return {*pre(a)==pre(*a)+1}; } a = &x Q() { {x==1},{x==2} = T,F; s = R(T,T); {a==pre(a)} {*pre(a)==pre(*a)} {*pre(a)=pre(*a)+1} pre(x)==1 and pre(*a)==pre(x) and *pre(a)==pre(*a)+1 and pre(a)==&x implies x==2 {x==1 } s

87 Newton: what changes with pointers? Simulation needs to handle pointer accesses Need to copy local heap across scopes to match Bebop’s semantics

88 void foo (int *a) { assume(*a > 5); assert(0); } main(int *x){ assume(*x < 5); foo(x); }

89 Contradictory! void foo (int *a) { assume(*a > 5); assert(0); } main(int *x){ assume(*x < 5); foo(x); } main: (1) x: X (2)*X: Y [1] foo : (3) a: A (4)*A: B [3] Conditions : (5)(Y< 5) [1,2] (6)(B < 5) [3,4,5] (7)(B > 5) [3,4] Predicates after simplification: *x 5

90 SLAM Imprecision due to Alias Imprecision (Flow Insensitivity) x = 0; y = 0; p = &y *p = *p + 1; assume(x!=0); p = &x; {x==0} {x==0} = T; skip; {x==0} = *; assume( !{x==0} ); skip; Pts-to(p) = { &x, &y}

91 x = 0; y = 0; p = &y if (p == &x) x = x + 1; else y = y + 1; assume(x!=0); p = &x; x = 0; y = 0; p = &y *p = *p + 1; assume(x!=0); p = &x; {x==0} = T; skip; {x==0} = *; assume(!{x==0} ); skip; Newton: Path is Infeasible

92 Consider values in abstract trace x = 0; y = 0; p = &y *p = *p + 1; assume(x!=0); p = &x; {x==0} = T; skip; {x==0} = *; assume(!{x==0} ); skip; {x==0} is true {x==0} is false INCONSISTENT

93 Consider values in abstract trace x = 0; y = 0; p = &y *p = *p + 1; assume(x!=0); p = &x; {x==0} = T; skip; {x==0} = *; assume(!{x==0} ); skip; WP(*p = *p +1, !(x==0) ) = ((p == &x) and !(x==-1)) or ((p != &x) and !(x==0)) (p!=&x) gets added as a predicate

94 What changes with pointers? C2bp –abstracting assignments –abstracting procedure returns Newton –simulation needs to handle pointer accesses –need to copy local heap across scopes to match Bebop’s semantics –need to refine imprecise alias analysis using predicates Bebop –remains unchanged!

95 What worked well? Specific domain problem Safety properties Shoulders & synergies Separation of concerns Summer interns & visitors –Sagar Chaki, Todd Millstein, Rupak Majumdar (2000) –Satyaki Das, Wes Weimer, Robby (2001) –Jakob Lichtenberg, Mayur Naik (2002) –Giorgio Delzanno, Andreas Podelski, Stefan Schwoon Windows Partners –Byron Cook, Vladimir Levin, Abdullah Ustuner

96 Future Work Concurrency –SLAM analyzes drivers one thread at a time –Work in progress to analyze interleavings between threads Rules and environment-models –Large scale development or rules and environment-models is a challenge –How can we simplify and manage development of rules? Modeling C semantics faithfully Theory: –Prove that SLAM will make progress on any property and any program –Identify classes of programs and properties on which SLAM will terminate

97 Further Reading See papers, slides from: http://research.microsoft.com/slam

98 Glossary Model checkingChecking properties by systematic exploration of the state-space of a model. Properties are usually specified as state machines, or using temporal logics Safety propertiesProperties whose violation can be witnessed by a finite run of the system. The most common safety properties are invariants ReachabilitySpecialization of model checking to invariant checking. Properties are specified as invariants. Most common use of model checking. Safety properties can be reduced to reachability. Boolean programs“C”-like programs with only boolean variables. Invariant checking and reachability is decidable for boolean programs. PredicateA Boolean expression over the state-space of the program eg. (x < 5) Predicate abstractionA technique to construct a boolean model from a system using a given set of predicates. Each predicate is represented by a boolean variable in the model. Weakest preconditionThe weakest precondition of a set of states S with respect to a statement T is the largest set of states from which executing T, when terminating, always results in a state in S.


Download ppt "Software Model Checking with SLAM Thomas Ball Testing, Verification and Measurement Sriram K. Rajamani Software Productivity Tools Microsoft Research"

Similar presentations


Ads by Google