LaRS

Document Sample
LaRS Powered By Docstoc
					Model-Driven Verification
Rajeev Joshi JPL Laboratory for Reliable Software

work done in collaboration with Alex Groce & Gerard Holzmann

Slides courtesy of Rajeev, with some changes I made for this class

11 March 2008

Model-Driven Verification

1

Model Checking with SPIN


Traditional approach


express design as a PROMELA model

I32 mkdir(const char *path) { ... res = lookup(path, cpath, &pt) ; if (res == ERROR) { return ERROR ; } else if (cpath[len] == '\0') { SET_ERRNO(EEXIST) ; return ERROR ; } ostat = sem_take(sem[pt]) ; }

manual translation

• Limitation

– verifies design, but not implementation – need to redo manual translation whenever implementation changes

inline mkdir_spec(d) { if :: exist[d] -> errno = EEXIST :: !exist[d] && !exist[par[d]] -> errno = ENOENT :: else -> exist[d] = 1 fi } ... active proctype main() { init() ; do :: choose(d) -> mkdir_spec(d) :: choose(f) -> creat_spec(f) ... od }

11 March 2008

Model-Driven Verification

2

Model-Driven Verification
 

Embed C program within SPIN model C code is executed by SPIN during backtracking search
c_decl { extern I32 mkdir(const char *path) ; } ; active proctype main() { init() ; do :: choose(d) -> c_code { mkdir(path[d]) ; } :: choose(f) -> c_code { creat(path[f]) ; } ... od }

I32 mkdir(const char *path) { ... res = lookup(path, cpath, &pt) ; if (res == ERROR) { return ERROR ; } else if (cpath[len] == '\0') { SET_ERRNO(EEXIST) ; return ERROR ; }

ostat = sem_take(sem[pt]) ;
}

Ref: Model-Driven Software Verification, G.J.Holzmann & R.Joshi, Proceedings of the 11th International SPIN Workshop, Barcelona 2004
11 March 2008 Model-Driven Verification

3

Simple Applications of Model-Driven Verification

11 March 2008

Model-Driven Verification

4

Checking stateless functions
Consider a procedure that converts UNIX pathnames to canonical form
void canonize(char *dst, const char *src) ;

Given the source string the function returns the string

/etc//tmp/../issue.net /etc/issue.net

11 March 2008

Model-Driven Verification

5

A Simple Correctness property
Define a boolean function Bool is_canonical(const char *str) which checks if a path is canonical (e.g., does not contain “//”)

We want to check that for any string S canonize(D, S); assert(is_canonical(D));

Note: This is a weak property, since check does not mention S!
Model-Driven Verification

11 March 2008

6

Checking canonize with Spin
c_decl { extern void canonize(char *, const char *); extern Bool is_canonical(const char *); char D[10]; }; byte S[10]; inline pick(i) { if :: S[i]='A' :: S[i]='B' ... :: S[i]='z' :: S[i]='.' :: S[i]='/' :: S[i] = '\0' fi } active proctype proc() { ... }
11 March 2008 Model-Driven Verification

7

Checking canonize with Spin
byte S[10]; inline pick(i) { if :: S[i]='A' :: S[i]='B' :: S[i] = 'C' :: ... :: S[i]='.' :: S[i]='/' :: S[i] = '\0' fi } active proctype proc() { pick(0);pick(1);pick(2);pick(3); S[4]='\0'; c_code { canonize(D, now.S); }; assert c_expr { is_canonical(D) } }

11 March 2008

Model-Driven Verification

8

State space reduction
Suppose source for canonize only checks against literals '/' '.' '\0'

Not hard to show that it is sufficient to use the following definition
inline pick(i) { if :: S[i]='A' :: S[i]='.' :: S[i]='/' :: S[i] = '\0' fi }

11 March 2008

Model-Driven Verification

9

Checking programs with state
Binary heap
16

Array representation
16 14 10 8 7 9 3 2 4

14

10

8

7

9

3

2

4

11 March 2008

Model-Driven Verification

10

Heap declarations
c_decl { void int int Bool setup (void); insert (int); extract_max(void); check_heap (void);

}

heap functions

int pos; int H[100]; } c_track c_track “&pos” “H”

}
“sizeof(int)”; “sizeof(int) * 100”;

heap state

}
11

11 March 2008

Model-Driven Verification

Spin model for checking Heap
inline pick(v, A, B) { atomic { v = A; do :: (v < B) -> v++ :: break od } }

same as assign v : A <= v <= B

11 March 2008

Model-Driven Verification

12

Spin model for checking Heap
active proctype proc() { c_code { setup(); }; do :: if :: c_expr { pos<100 } -> pick(val, 1, 101); c_code { insert(now.val); } :: c_expr { pos > 0 } -> c_code { int v = extract_max(); } fi assert c_expr { check_heap() } od }
Model-Driven Verification

11 March 2008

13

Use of Abstractions with Model-Driven Verification

11 March 2008

Model-Driven Verification

14

Spin's nested dfs algorithm
proc dfs1(s) { push s on Stack1 add (s,0) to States for each (s, a, s') do if (s',0) 	States then dfs1(s')  if accepting(s) seed := (s,1); dfs2(s) pop s from Stack1 }

proc dfs2(s) { push s on Stack2 add (s,1) to States for each (s, a, s') do if (s',1) = seed then report cycle else if (s',1)  States then dfs2(s') 	 pop s from Stack2 }
15

11 March 2008

Model-Driven Verification

Nested dfs with abstraction function A(.)
proc dfs1(s) { push s on Stack1 add (A(s),0) to States for each (s, a, s') do if (A(s'),0)  States then dfs1(s') 	 if accepting(A(s)) seed := (A(s),1); dfs2(s) pop s from Stack1 proc dfs2(s) { } push s on Stack2 add (A(s),1) to States for each (s, a, s') do if (A(s'),1) = seed then report cycle else if (A(s'),1) 	 States then dfs2(s') pop s from Stack2 }
11 March 2008 Model-Driven Verification

16

Model-Driven Verification with Abstraction
Example: program has integer variables x,y abstraction function is (x+y)‫‏‬
c_decl { int x, y ; int a ; void abst(void) { } c_track c_track c_track “&x” “&y” “&a”

a = x+y ; } “UnMatched” ; “UnMatched” ; “Matched” ;

“sizeof(int)” “sizeof(int)” “sizeof(int)”

11 March 2008

Model-Driven Verification

17

Computing abstraction function
Need to update abstraction function after any changes to x,y

Instead of
c_code { compute(&x, &y); } we write c_code { compute(&x, &y); abst(); }

11 March 2008

Model-Driven Verification

18

Soundness of abstraction
Not all abstractions preserve soundness and completeness Consider the abstraction function (x+y)with the following code:
active proctype proc() { c_code { x=y=0; abst(); }; do :: c_code { x=(x+1)%M; y=(y+1)%N; abst(); }; assert c_expr { (x+y)%2 == 0 } od }

Exercise: show that abstraction is unsound if either M,N is odd (Hint: try with M=3,N=4)
11 March 2008 Model-Driven Verification

19

Soundness of abstraction function A
Define the equivalence relation ~ as s~t ≡ A(s) = A(t) Lemma. Following conditions are sufficient for soundness

(1) ~ is a bisimulation
for any w,y,z there exists x satisfying

y
~

z
~ x

w

(2) all atomic propositions P are preserved by ~
for any w,y such that w ~ y P(w) ≡ P(y)
11 March 2008 Model-Driven Verification

20

When soundness is unachievable
For large programs, state vectors can be quite large (10s or 100s of KB), and even the best abstractions may not reduce the state space enough to fit into memory

In such cases, unsound abstractions can be useful -- cannot show absence of errors -- but can quickly find bugs Example: statement coverage, path coverage

11 March 2008

Model-Driven Verification

21

Model-Driven Verification in Practice

11 March 2008

Model-Driven Verification

22

Tracking and Matching
Some data should be neither tracked or matched - data that does not change after initialization - data that does not affect search or properties of interest - data that computes cumulative or statistical information over the model checking run

Some data should be matched but not tracked - value computed by abstraction function

Some data is hard to track - system heap

11 March 2008

Model-Driven Verification

23

Modeling system resource: system heap
Suppose we want to check a program that uses malloc()‫‏‬ Difficulty: can't use c_track because heap is outside our control Solution: implement an allocator that allocates from fixed region

P

N bytes

Note: must track all state relevant to the allocator Similar approach can be used for other system resources -- e.g., filesystem, storage devices
11 March 2008 Model-Driven Verification

24

Application of Model-Driven Verification randomizing choice in Spin
Recall macro for choosing v satisfying A <= v <= B
inline pick(v, A, B) { atomic { v := A; do :: (v < B) -> v++ :: break od } }

Typical usage
do :: pick(x, 5, 7) ; pick(y, 5, 7) ; pick(z, 5, 7) ; c_code { f(x,y,z) ; }; ... od
25

11 March 2008

Model-Driven Verification

How Spin explores transitions
x=7 x=5 x=6

pick(x, 5, 7)

y=5

y=6 y=7

y=5

y=6 y=7

pick(y, 5, 7)

Note: choices are always in the same (fixed) order -- not desirable during an incomplete search
11 March 2008 Model-Driven Verification

26

Randomizing choice in Spin
LS0

x=7 x=5
LS1

pick(x, 5, 7)
LS1

x=6
LS1

y=7
LS2

y=5 y=6
LS2 LS2

y=7
LS2

y=5 y=6
LS2 LS2

pick(y, 5, 7)

Note: better, but choices at any given level are still in same order Exercise (**): fix solution so that choices are properly randomized
11 March 2008 Model-Driven Verification

27

Advanced Topics

11 March 2008

Model-Driven Verification

28

Limitations of Model-Driven Verification
(a) cannot check properties within embedded C code (b) cannot interrupt control flow within a C function e.g., to simulate an exception (c) cannot interleave different C functions for checking multithreaded C code

Address (a) and (b) using program instrumentation
Ref: Extending Model Checking with Dynamic Analysis, Alex Groce & Rajeev Joshi, Proceedings VMCAI, San Francisco, Jan 2008

11 March 2008

Model-Driven Verification

29

Checking Multithreaded C code
Example: Peterson's algorithm (adapted from wikipedia)
struct pa_desc d; pa_desc_init(&d, 0); for (;;) { *(d.f0)=1; last=d.last ; while (*(d.f1)==1 && (last==d.last)) { ; // busy wait } // critical section struct pa_desc d; pa_desc_init(&d, 0); for (;;) { *(d.f0)=1; last=d.last ; while (*(d.f0==1) && (last==d.last)) { ; // busy wait } // critical section

d.f0=0;
} }

d.f1=0;

Thread 0
11 March 2008 Model-Driven Verification

Thread 1
30

Checking multithreaded code with Spin
pancam project at LaRS (joint work with Anna Zaks, NYU)
pancam is a virtual machine for C programs that can be embedded within SPIN





compiles a multithreaded C program to LLVM assembly code stateless – can be executed from a given program state provides ability to execute any number of instructions of a specific thread and check given properties at any point
spin -a

Spin model

pan.c

pancam VM take_step(tid) { ... }

llvm-gcc

C program
11 March 2008

LLVM IR
Model-Driven Verification

31

pancam state

global state

system heap

FE RE

program stack

concrete state cs[N]

c_track

“cs”

“N”

“UnMatched”;

11 March 2008

Model-Driven Verification

32

Spin model for pancam
int tid; /* thread to execute next */

active proctype main() { c_code { pancam_init(); start_program_threads(); }; do :: pick(tid); c_expr { enabled(tid) } -> c_code { take_step(tid); } od }

11 March 2008

Model-Driven Verification

33

Adding abstraction function to pancam

global state

system heap

FE RE

program stack

concrete state cs[N] c_track c_track “cs” “as” “N” “K” “UnMatched”; “Matched”;

abstract state as[K]

User must provide function compute_abst(void *as) which assigns as[..] based on current value of cs[..]
11 March 2008 Model-Driven Verification

34

pancam project


Status
   

initial version of pancam VM tested on small programs (~ 200 lines) found bug in Wikipedia implementation of Peterson's algorithm: missing volatile keyword in declaration developed method for reducing atomicity on the fly (“superstep reduction”)



Ongoing work
 

adding liveness checking optimizations, e.g., using deltas to reduce state vectors
Model-Driven Verification

11 March 2008

35

Multi-core Spin


each core does a dfs core can “hand off” a state S to neighbor, and continue search as if S was fully explored matched states are stored in shared table, tracked state are stored on local stacks special algorithms used to detect termination
36

worker 1

shared work queues

root 0

shared state space

worker 2


worker 3


Figure provided by Gerard Holzmann
11 March 2008 Model-Driven Verification

Model-Driven verification with multi-core Spin
Using multi-core Spin for PROMELA models $ gcc -DNCORE=4 pan.c -o pan

Problem: can't directly use this for C code
active proctype proc() { only gets executed c_code { setup(); }; on first core! do :: pick(x, 3, 5); c_code { foo(now.x, &now.y); }; ... }

Solution: each core should execute setup() during initialization
$ gcc -DNCORE=4 “-DC_INIT=start()” pan.c -o pan
11 March 2008 Model-Driven Verification

37

Conclusion


Model-Driven Verification with Spin is an attractive way to check implementation code in C
  

easy to set up compatible with almost all features of Spin: checking LTL properties, bit-state hashing, multi-core Spin not compatible with: breadth-first search, partial-order reduction, simulation mode



In practice, biggest challenges are
 

state space explosion: use abstraction (sound or unsound) C code is executed as atomic step: use code instrumentation; use special Virtual Machine
Model-Driven Verification

11 March 2008

38

References
Logic Verification of ANSI-C Code with Spin, G.J.Holzmann, SPIN 2000

Model-Driven Software Verification, G.J.Holzmann & R.Joshi, SPIN 2004
Extending Model Checking with Dynamic Analysis, Alex Groce & Rajeev Joshi, VMCAI 2008 The Design of a multi-core extension of the Spin Model Checker, G.J.Holzmann & D. Bosnacki, IEEE Transactions on Software Engineering, Vol 33, Nr 10

11 March 2008

Model-Driven Verification

39


				
DOCUMENT INFO
Shared By:
Categories:
Stats:
views:81
posted:11/8/2009
language:English
pages:39