11 march 2008 1 model-driven verification rajeev joshi jpl laboratory for reliable software work...
Post on 20-Dec-2015
213 views
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 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 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 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 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