Verifying Concurrent Message- Passing C Programs with Recursive Calls Sagar Chaki, Edmund Clarke,...

Post on 26-Dec-2015

217 views 1 download

Tags:

Transcript of Verifying Concurrent Message- Passing C Programs with Recursive Calls Sagar Chaki, Edmund Clarke,...

Verifying Concurrent Message-Passing C Programs with Recursive Calls

Sagar Chaki, Edmund Clarke, Nicholas Kidd, Thomas Reps, and Tayssir Touili

Our Contributions

New model-checking techniques for Communicating Pushdown SystemsMulti-level semi-decision procedure

Addresses 3 challenging verification issuesLarge and infinite domainsRecursionConcurrency and synchronization

Implemented on top of model checker MAGIC

Real Bugs!

2 process race condition found in Windows NT Bluetooth Driver [KISS 04]

New 3 process race condition found in “corrected” version of Windows NT Bluetooth driver Found while attempting to verify the driver

Model checking

Program is a collection of states

Program statements define transitions in state space

Model checking

Predicate abstraction generates model of program Check model against a specification

ModelSpec

Concurrent model checking

Multiple transition systems

Model 1 Model 2

Predicate abstraction generates multiple models Combine models and check specification

Spec

Related Work

SLAM No concurrency

BLAST and MAGIC No recursion

KISS 2 context switches

k-bounded context switches Under-approximation No implementation

Outline

Pushdown Systems Review Communicating Pushdown Systems Experiments

Pushdown Systems (PDS)

Finite state machine with a stack (P, , ) P = {p, q, ...} : finite set of states : finite set of stack symbols Configuration c P £ * : finite set of rules µ (P £ ) £ (P £ *)

if h p, i ! h q, i then h p, i ) h q, i *

Pushdown System from a CFG

void f() { if( e1 ) { messagea

f() messageb

}}

fenter

messagea

e1

fexit

messagebcallf

retf

PDS encoding of function f

• p,fenter!p,e1 fenter

messagea

e1

fexit

messagebcallf

retf

• p,messageb!p,fexit

• p,retf!p,messageb

• p,e1!p,messagea

• p,e1!p,fexit

• p,callf!p,fenter retf

• p,messagea!p,callf

• p,fexit!p,"

PDS encoding of a CFG

Intraprocedural edgep, 1p,

Interprocedural call edge p, 1p,

Interprocedural return edge p, 1p,

fenter

messagea

e1

fexit

messagebcallf

retf

PDS Reachability Queries

Let C be a set of PDS configurations {c1, …, cn}

pre*(C) backwards reachability from C post*(C) forwards reachability from C If C is regular, then pre*(C) (post*(C)) is regular

PDS Reachability Example

fenter

messagea

e1

fexit

messagebcallf

retf

fenterp

retf

fenter, e1, messagea, callfp

retf

fenter, e1,

messagea,

callf, messageb, retf, fexit, "

messageb, retf, fexit, "

Model checking PDS

Is C reachable from C? If C is regular, then pre*(C) is regular Model checker checks configuration reachability I.e., is C pre*(C) =

Concurrent Message-Passing Program

void f() { if( e1 ) { messagea

f() messageb

}}

void g() { if( e2 ) { messagea

messageb

g() } else { messageb

}}

Reachability isn’t enough!

Does not capture inter-process synchronization Must associate synchronization messages with

execution paths Solution - Communicating Pushdown Systems

Model a process by language of synchronization messages Language intersection checks inter-process reachability

Outline

Review of Pushdown Systems Communicating Pushdown Systems Experiments

Communicating Pushdown Systems (CPDS)• CPDS CP is a tuple of PDSs 1 … , n• Global configuration of CP is a tuple of PDS

configurations g = c1 … , cn• Set of global actions (Act) = {Lab}

• {Lab} set of synchronizing actions• represents an internal action

Concurrent Message-Passing Program

void f() { if( e1 ) { messagea

f() messageb

}}

void g() { if( e2 ) { messagea

messageb

g() } else { messageb

}}

CPDS for Message-Passing Program

CP = (Pf, Pg)

Configuration g = (cf,cg)

Act = {a, b, }

Reachability Analysis of CPDS

• “From c1c2, is c1c2

reachable?”

• True if Lc1c1 Lc2c2

[BET03]• L1 = Lc1c1

& L2=Lc2c2

• What is L1 & L2?

Process’s Language of Messages

void f() { if( e1 ) { messagea

f() messageb

}}

L( f )

"abaabbaaabbbaaaabbbb

Language of Synchronizing Messages

void f() { if( e1 ) { messagea

f() messageb

}}

L( f ) akbk

Generating the Process Language

Use Weighted Pushdown SystemAssociates weight to each valid pathReachability query returns “combined” weight

over all valid paths“Combined” weight is the language of

synchronizing messages for each process

Language of Synchronizing Messages

void f() { if( e1 ) { messagea

f() messageb

}}

L( f ) akbk

Language of Reachability in WPDS

fenter

messagea

e1

fexit

messagebcallf

retf

L( p,fenter , p, fexit ) akbk

Problem: L1 L2 = is undecidable!

L( p,fenter , p, fexit ) L( p,fenter , p, fexit )

akbk akbk

fenter

messagea

e1

fexit

messagebcallf

retf

fenter

messagea

e1

fexit

messagebcallf

retf

Multi-level semi-decision procedure

Level 1 in MAGIC Extract CPDS from C program Query Level 2

Level 2 in WPDS++ use CounterExample Guided Abstraction Refinement

(CEGAR) Over-approximate Li as Ai using ith-prefix

Ai is regular because it is finite!

ith-prefix

Associate finite string to each path in WPDS String length can be at most i

Bounded string concatenation

Over-approximates CFL for a process Separate concrete from abstract strings

Defines a set of refinable finite chain abstractions

ith-prefix - 2 recursive calls

fenter

messagea

e1

fexit

messagebcallf

retf

• i∞ = aabb• i5 = aabb• i3 = aab

• 3(aab) = aab(a+b)*

ith-prefix

L( p,fenter , p, fexit )fenter

messagea

e1

fexit

messagebcallf

retf

i1 = {", a }i2 = {", aa, ab }i3 = {", ab, aaa, aab }i4 = {", ab, aaaa, aaab, aabb }i5 = {", ab, aabb, aaaaa,

aaaab, aaabb }…

Level 2 CEGAR semi-decision procedure

Given CP, c1c2 , and c1c2

Let Ci = ci Pre*(Pi, ci

)

Let Ai = over all paths in Ci

Let I = A1 A2

Level 2 CEGAR semi-decision procedure

• If I = then L1 L2 = • L(c1c2 , c1

c2) I

• If I contains concrete string, report back the shortest counterexample

• Else, increment i and repeat

CPDS Example

L( p,fenter , p, fexit ) L( p,genter , p, gexit )

fenter

messagea

e1

fexit

messagebcallf

retf

genter

messagea

e2

gexit

messageb

messageb

callg

retg

CPDS Example

i1 = {", a} i1 = {a, b}

L( p,fenter , p, fexit ) L( p,genter , p, gexit )

fenter

messagea

e1

fexit

messagebcallf

retf

genter

messagea

e2

gexit

messageb

messageb

callg

retg

CPDS Example

1(i1 = {", a}) = "+a(a+b)*

1( i1 = {a,b}) = (a+b)(a+b)*

L( p,fenter , p, fexit ) L( p,genter , p, gexit )

fenter

messagea

e1

fexit

messagebcallf

retf

genter

messagea

e2

gexit

messageb

messageb

callg

retg

CPDS Example

i2 = {",ab} i2 = {b,ab}

L( p,fenter , p, fexit ) L( p,genter , p, gexit )

fenter

messagea

e1

fexit

messagebcallf

retf

genter

messagea

e2

gexit

messageb

messageb

callg

retg

CPDS Example

i3 = {",ab,aaa,aab} i3 = {b,aba,abb}

L( p,fenter , p, fexit ) L( p,genter , p, gexit )

fenter

messagea

e1

fexit

messagebcallf

retf

genter

messagea

e2

gexit

messageb

messageb

callg

retg

CPDS Example

= i3 = {",ab,aaa,aab} i3 = {b,aba,abb}

L( p,fenter , p, fexit ) L( p,genter , p, gexit )

fenter

messagea

e1

fexit

messagebcallf

retf

genter

messagea

e2

gexit

messageb

messageb

callg

retg

Experiment - Bluetooth Driver

Abstract Bluetooth driver from Windows NT Reentrant multi-threaded library Has known bug -- found by KISS [QW04] Two handler processes: receive one request each

2 context switches: RUN; STOP; RUN Modeled with a CPDS

Counterexample consists of 8 actions Found in 5 seconds, using 334 MB

Bluetooth CPDS Model

CPDS uses 5 processes Two handler processes

RUN STOP

Three processes that model global variables 2 Booleans 1 integer counter

Experiment 2 – Revised Bluetooth Driver

“Corrected” version of model in which KISS found a bug Challenge: Could we verify that it was correct? Answers obtained by CPDS model checking:

For 2 processes (RUN, STOP) … correct! For 3 processes (RUN1, RUN2, STOP) … incorrect

Six processes in CPDS model Three handler processes (RUN1, RUN2, STOP) Three processes for globals (2 Booleans, 1 integer counter)

Counterexample consisted of 14 actions Found in 20 seconds, using 391 MB

“Correct” Bluetooth Bug

n0: rc = atomicIncr();

n1: if( rc ) {

n2: // do work

n3: assert(Counter);

}

n4: atomicDecr();

RUN1 STOP RUN2

n2 decr;wait;

n1

n4

cleanupn3

Counter: 0Counter: 1Counter: 2Counter: 1

Conclusion

Model each process as a language of messages

L1 L2

Combine languages via intersection Reachability is emptiness of intersection

= Ø?

Questions?

Thank You

Nicholas KiddUniversity of Wisconsin-Madison