+ All Categories
Home > Documents > 11 March 2008 1 Model-Driven Verification Rajeev Joshi JPL Laboratory for Reliable Software work...

11 March 2008 1 Model-Driven Verification Rajeev Joshi JPL Laboratory for Reliable Software work...

Date post: 20-Dec-2015
Category:
View: 213 times
Download: 0 times
Share this document with a friend
39
11 March 2008 1 Model-Driven Verification 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
Transcript

11 March 2008 1Model-Driven Verification

Model-Driven Verification

Rajeev Joshi

JPL Laboratory for Reliable Software

work done in collaboration withAlex Groce & Gerard Holzmann

Slides courtesyof Rajeev, withsome changesI made for thisclass

11 March 2008 2Model-Driven Verification

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]) ;

}

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}

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

manual

translation

11 March 2008 3Model-Driven Verification

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}

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

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]) ;

}

11 March 2008 4Model-Driven Verification

Simple Applications ofModel-Driven Verification

11 March 2008 5Model-Driven Verification

Checking stateless functions

void canonize(char *dst, const char *src) ;

Consider a procedure that converts UNIX pathnames to canonical form

Given the source string /etc//tmp/../issue.netthe function returns the string /etc/issue.net

11 March 2008 6Model-Driven Verification

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!

11 March 2008 7Model-Driven Verification

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 8Model-Driven Verification

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 9Model-Driven Verification

State space reduction

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

inline pick(i) { if :: S[i]='A' :: S[i]='.' :: S[i]='/' :: S[i] = '\0' fi}

Not hard to show that it is sufficient to use the following definition

11 March 2008 10Model-Driven Verification

Checking programs with state

Binary heap

14 10

8 9

16

7 3

2 4

14 10 8 7 9 3 2 416

Array representation

11 March 2008 11Model-Driven Verification

Heap declarations

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

int pos; int H[100];}

heapfunctions}

heapstate

}

}

c_track “&pos” “sizeof(int)”;c_track “H” “sizeof(int) * 100”;

11 March 2008 12Model-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 13Model-Driven Verification

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}

11 March 2008 14Model-Driven Verification

Use of Abstractionswith Model-Driven Verification

11 March 2008 15Model-Driven Verification

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}

11 March 2008 16Model-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 17Model-Driven Verification

Model-Driven Verification with Abstraction

c_decl { int x, y ; int a ; void abst(void) { a = x+y ; }}

c_track “&x” “sizeof(int)” “UnMatched” ;c_track “&y” “sizeof(int)” “UnMatched” ;

c_track “&a” “sizeof(int)” “Matched” ;

Example: program has integer variables x,y abstraction function is (x+y)

11 March 2008 18Model-Driven Verification

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 19Model-Driven Verification

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 20Model-Driven Verification

Soundness of abstraction function A

Define the equivalence relation ~ as s~t ≡ A(s) = A(t)

y z

xw

~ ~

(1) ~ is a bisimulation

for any w,y,z there exists x satisfying

(2) all atomic propositions P are preserved by ~

for any w,y such that w ~ y P(w) ≡ P(y)

Lemma. Following conditions are sufficient for soundness

11 March 2008 21Model-Driven Verification

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 22Model-Driven Verification

Model-Driven Verificationin Practice

11 March 2008 23Model-Driven Verification

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 is hard to track

- system heap

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

11 March 2008 24Model-Driven Verification

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

N bytesP

Solution: implement an allocator that allocates from fixed region

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 25Model-Driven Verification

Application of Model-Driven Verificationrandomizing choice in Spin

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

Recall macro for choosing v satisfying A <= v <= B

Typical usage

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

11 March 2008 26Model-Driven Verification

How Spin explores transitions

pick(x, 5, 7)x=7

x=6x=5

y=5 y=6 y=7 y=5 y=6 y=7pick(y, 5, 7)

Note: choices are always in the same (fixed) order -- not desirable during an incomplete search

11 March 2008 27Model-Driven Verification

Randomizing choice in Spin

pick(x, 5, 7)x=7

x=6x=5

y=7 y=5 y=6 y=7 y=5 y=6pick(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

LS0

LS1 LS1 LS1

LS2 LS2 LS2 LS2 LS2 LS2

11 March 2008 28Model-Driven Verification

Advanced Topics

11 March 2008 29Model-Driven Verification

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

Ref: Extending Model Checking with Dynamic Analysis,Alex Groce & Rajeev Joshi, Proceedings VMCAI, San Francisco, Jan 2008

Address (a) and (b) using program instrumentation

11 March 2008 30Model-Driven Verification

Checking Multithreaded C code

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

d.f0=0;}

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.f1=0;}

Thread 0 Thread 1

Example: Peterson's algorithm (adapted from wikipedia)

11 March 2008 31Model-Driven Verification

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 model pan.cspin -a pancam VM

C programllvm-gcc

LLVM IR

take_step(tid) { ...}

11 March 2008 32Model-Driven Verification

pancam state

concrete state cs[N]

globalstate

systemheap

programstack

FREE

c_track “cs” “N” “UnMatched”;

11 March 2008 33Model-Driven Verification

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 34Model-Driven Verification

Adding abstraction function to pancam

concrete state cs[N] abstract stateas[K]

globalstate

systemheap

c_track “cs” “N” “UnMatched”;c_track “as” “K” “Matched”;

globalstate

systemheap

programstack

FREE

User must provide function compute_abst(void *as)which assigns as[..] based on current value of cs[..]

11 March 2008 35Model-Driven Verification

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

pancam project

11 March 2008 36Model-Driven Verification

Multi-core Spin

root0

sharedstate

space

worker1

worker2

worker3

sharedworkqueues

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 terminationFigure provided by Gerard Holzmann

11 March 2008 37Model-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 codeactive proctype proc() { c_code { setup(); }; do :: pick(x, 3, 5); c_code { foo(now.x, &now.y); }; ...}

only gets executed on first core!

Solution: each core should execute setup() during initialization

$ gcc -DNCORE=4 “-DC_INIT=start()” pan.c -o pan

11 March 2008 38Model-Driven Verification

Conclusion

Model-Driven Verification with Spin is an attractive wayto 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

11 March 2008 39Model-Driven Verification

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


Recommended