• No results found

Sequentializationtargetedto BoundedModel-Checkers

N/A
N/A
Protected

Academic year: 2021

Share "Sequentializationtargetedto BoundedModel-Checkers"

Copied!
58
0
0

Loading.... (view fulltext now)

Full text

(1)

Sequentialization targeted to

Bounded Model-Checkers

Salvatore La Torre

Dipartimento di Informatica

(2)

• Code-to-code translation from a multithreaded program to an

“equivalent” sequential one

Conc. program

Sequentialization

T1 T2 Tm shared vars …

loc loc loc

• Re-use of existing tools (delegate the analysis to the

backend tool)

• Fast prototyping (designers can concentrate only

concurrency features)

• Can work with different backends

Seq. Verifier

Seq. progam

(3)

Sequentialization

alters the original program structure by

injecting control code

(which is an overhead for the backend)

requires careful attention to the details of

the translation for well-performing tools

(4)

Backend: Bounded Model Checkers

• Reduce program verification to SAT/SMT solvers

• Very effective technique to discover bugs in seq. programs

• Performance relies on the performance of underlying

solvers

• Impressive improvement of

SAT solvers in last years

1 10 100 1000 10000 100000 1960 1970 1980 1990 2000 2010 Year V a rs

(5)

Implementations with BMC backend

• LR seq. [Lal-Reps, CAV’08]: eager, bounded round-robin

• LMP seq. [La Torre-Madhusudan-Parlato]: lazy, any scheduling • With BMC, LR works better than LMP

[Ghafari-Hu-Rakamaric, SPIN’10]

• Implementations of LR:

– CSeq: Pthreads C programs [Fischer-Inverso-Parlato, ASE’13] – STORM: also dynamic memory allocation

[Lahiri-Qadeer-Rakamaric, CAV’09]

– Corral [Lal-Qadeer-Lahiri, CAV’12]

– Delay bounded-scheduling [Emmi-Qadeer-Rakamaric, POPL’11]

(6)

Lal/Reps Sequentialization

considers only round-robin schedules

with k rounds

thread function, run to completion • global memory copy for each round

scalar array

• context switch round counter++ • first thread starts with

nondeterministic memory contents

– other threads continue with content left by predecessor

T0 T1 S2,1 S0,1 S1,1 Sk,1 Tn ... ... ... ... ... ... S2,0 S0,0 S1,0 Sk,0 S2,n S0,n S1,n Sk,n

(7)

Lal/Reps Sequentialization

considers only round-robin schedules

with k rounds

thread function, run to completion • global memory copy for each round

scalar array

• context switch round counter++ • first thread starts with

nondeterministic memory contents

– other threads continue with content left by predecessor • checker prunes away inconsistent simulations

– assume(Si+1,0 == S i,n);

– requires second set of memory copies

– errors can only be checked at end of simulation • requires explicit error checks

T0 T1 S2,1 S0,1 S1,1 Sk,1 Tn ... ... ... ... ... ... S2,0 S0,0 S1,0 Sk,0 S2,n S0,n S1,n Sk,n

(8)

CSeq Tool Architecture

[Fischer-Inverso-Parlato, ASE’13]

• pycparser, AST traversal with unparsing

– insert new type declarations, modify memory accesses

insert context switch simulation code at each sequence pointinsert explicit error checks

– insert checker and code for pthread functions

sequential non-deterministic C program P' concurrent C program P SAFE UNSAFE CSeq sequential tool k, N

(9)

Can we improve this?

Eager

sequentializations

cannot rely on error checks built into the

backend

also requires specific techniques to handle

programs with heap-allocated memory

LR (but also LMP) uses additional copies of

shared variables

BMC will make more copies with

loop/recursion unwinding

(10)

Two new sequentializations

[Inverso-Tomasco-Fischer-LaTorre-Parlato]

Lazy-CSeq [CAV’14-TACAS/SVCOMP’14]

lazy

light-weight: few additional variables and code

MU-CSeq [TACAS/SVCOMP’14]

Bound on memory unwindings

(11)

Outline

Bounded Model-checking for programs

Lazy sequentialization: Lazy-CSeq

Memory unwindings: MU-CSeq

Experiments

(12)

How does it work

Transform a programs into a set of equations

Simplify control flow

Unwind all of the loops

Convert into Static Single Assignment (SSA)

Convert into equations

Bit-blast

Solve with a SAT Solver

(13)

Control Flow Simplifications

• All side effect are removed

– e.g., j=i++ becomes j=i; i=i+1

• Control Flow is made explicit

– continue, break replaced by goto

• All loops are simplified into one form – for, do, while replaced by while

(14)

Loop Unwinding

while() loops are unwound iteratively

Break / continue replaced by goto void f(...) { void f(...) { ... while(cond) { Body; } Remainder; }

(15)

Loop Unwinding

while() loops are unwound iteratively

Break / continue replaced by goto void f(...) { void f(...) { ... if(cond) { Body; while(cond) { Body; } } Remainder; }

(16)

Loop Unwinding

while() loops are unwound iteratively

Break / continue replaced by goto void f(...) { void f(...) { ... if(cond) { Body; if(cond) { Body; while(cond) { Body; } } } Remainder; }

(17)

Unwinding assertion

while() loops are unwound iteratively

Break / continue replaced by goto

Assume statements inserted after last iteration: block execution if program runs longer than bound permits

void f(...) { void f(...) { ... if(cond) { Body; if(cond) { Body; if(cond) { Body; while(cond) { Body; } } } } Remainder; }

(18)

Unwinding assertion

while() loops are unwound iteratively

Break / continue replaced by goto

Assume statements inserted after last iteration: block execution if program runs longer than bound permits

void f(...) { void f(...) { ... if(cond) { Body; if(cond) { Body; if(cond) { Body; assume(!cond); } } } } Remainder; } Unwinding assume

(19)

Transforming Loop-Free Programs Into

Equations (1)

Easy to transform when every variable is only

assigned once!

x = a; y = x + 1; z = y – 1; Program Constraints x = a && y = x + 1 && z = y – 1 &&

(20)

Transforming Loop-Free Programs Into

Equations (2)

When a variable is assigned multiple times,

use a new variable for the RHS of each

assignment

(21)

What about conditionals?

Program SSA Program

if (v) x = y; else x = z; w = x; if (v0) x0 = y0; else x1 = z0; w1 = x??; What should ‘x’ be?

(22)

What about conditionals?

For each join point, add new variables with

selectors

Program SSA Program

if (v) x = y; else x = z; w = x; if (v0) x0 = y0; else x1 = z0; x2 = v0 ? x0 : x1; w1 = x2

(23)
(24)

CBMC: Bounded Model Checker for C

A tool by D. Kroening/Oxford and Ed Clarke/CMU

Parser Static Analysis

CNF-gen SAT solver CEX-gen CBMC C Program SAFE UNSAFE + CEX SAT UNSAT CNF goto-program equations

(25)

BMC: from sequential to concurrent

• BMC for sequential programs has been used to discover subtle

errors in applications

• robust BMC tools exist for C programs (e.g. CBMC, LLBMC,

ESBMC)

• attempts to apply BMC to multi-threaded programs face

problems

number of interleavings grows exponentially with #threads and #statements

Recent solutions for multi-threaded programs

• partial orders

(26)

Outline

Bounded Model-checking for programs

Lazy sequentialization: Lazy-CSeq

Memory unwindings: MU-CSeq

Experiments

Conclusions

(27)

Lazy-CSeq schema

P' simulates all computations (up to K rounds) of P • lazy: avoid exploring unfeasible runs

(28)

Lazy-CSeq Sequentialization

Translation

P

P'

:

unwinding, inlining (bounded program)

thread T

function

T

'

main driver:

For each round in [1..K]

for each thread in [1..N]

(29)

Main driver

K: rounds

ct: thread count

active[j]: true iff thread j is active

cs: guessed context-switch

position for coming simulation pc[j]: position when

context-switched out of thread j size[j]: last position for

context-switches

void main(void) {

for(r=1; r<=K; r++) { ct=1; // thread 1

if(active[ct]) { //only active theads cs=pc[ct]+nondet uint(); // guess cs assume(cs<=size[ct]); // legal? fseq_1(arg[ct]); // simulate thread pc[ct]=cs; // store cs } : : : : : : : : : ct=n; // thread n if(active[ct]) { : : : : : : : : : } }}

(30)

Thread T

function T'

Translation PP': – unwinding, inlining – thread T ↝ function T' – main driver: • for round in [1..K] • for thread in [1..N] • T'thread (); Thread T ↝ function T'

• var x; ↝ static var x; • stmt; ↝ guard; stmt;

T'

(31)

..

.

Thread T

function T'

T'

Thread simulation: round 1

guess context-switch point cs1 (in main)

• execute stmts before cs1

jump in multiple hops to the end

and return

Thread T ↝ function T'

• var x; ↝ static var x;

• stmt; ↝ guard; stmt; context-switch cs 1 .. . simulation round 1 e x e c sk ip

(32)

..

.

Thread T

function T'

Thread simulation: round i

guess context-switch point csi (in main) jump in multiple hops to pci-1

execute stmts from pci-1 to csijump in multiple hops to the end

and return

Thread T ↝ function T'

var x;static var x;stmt; ↝ guard; stmt; simulation round i >1 T' context-switch csi .. . e x e c sk ip sk ip

(33)

Instrumenting jumping

in and out of

thread executions

(stmt;

↝ guard; stmt;

)

Multiple hops:

#define J(A,B) if ( pc[ct] > A || A >= cs )

goto B;

Ex. At position 5,

J(5,6) jumps to 6 (next position)

when not in [ pc[ct], cs [

(34)

Branching stmts

Use macro:

#define G(L) assume(cs >= L);

• Rules out spurious thread executions

when context-switch position is inside the not picked branch

Thread T ↝ function T'

• var x; ↝ static var x; • stmt; ↝ guard; stmt; if cond { body1

}else{ body2 } if cond { body1 }else{ G(A) body2 } G(B)

(35)

Example

2:J(2,3) if(c>0) 3:J(3,4) c++; else { 4:J(4,5) c=0; if(!(tmp>0)) goto l1; 5:J(5,6) c++; tmp--; if(!(tmp>0)) goto l1; 6:J(6,7) c++; tmp--; assume(!(tmp>0)); l1: G(7); } G(7)

7:J(7,8) pthread mutex unlock(&m);

Assume pc=2 and cs=3

(only 2: must be executed) Additionally suppose c<=0 holds Execution jumps to the else stmt and exits

In main pc is then set to 3 (cs)

When resumed, the tread will start from 3:

executing c++!!!!!

Adding guard G(4) right after the

else stmt rules out this unfeasible computation

G(4)

Note this is not ruling out

any good exectutions

The sketched one is captured by

guessing cs=4 instead of cs=3

(36)

Outline

Bounded Model-checking for programs

Lazy sequentialization: Lazy-CSeq

Memory unwindings: MU-CSeq

Experiments

(37)

Main idea

Guess a

memory unwinding

of the shared memory

sequence of writes into the shared memory of

an execution

Execute each thread s.t. its local computation is

consistent with the memory unwinding

any scheduling that fits it is considered

Crucial notion: all the shared memory operations

(38)

Memory object

Stores a sequence of writes

Each write is a triple

(thread, variable, value)

Is used through an interface

(39)

Memory object interface

int mem_init(uint V, uint W, uint T);

instantiate a memory object

V = number of variables

W = number of writes

(40)

Memory object interface

int read(uint th_id, uint var);

void write(uint th_id, uint var, int value);

int mem_thread_create(uint parent_id);

returns id for created thread

void terminate(uint th_id);

checks that all writes of th_id have been

executed

………

(41)

MU-Cseq sequentialization

A funciton for each thread

thread T

function

T

'

main driver

:

void proc main(void)

call memory_init(V, W, T);

// instantiate memory

ct := mem_thread_create(0);

// register main thread

call main

W;T

(x1,..., xk);

call terminate(ct); // all writes are executed

assert(_error != 1)

// error check

(42)

Basic Idea:

• uses auxiliary variables

– pos (current index into memory object) – ct (id of currently simulated thread)

• every thread is translated into a function

– simulation starts from main thread

• each thread creation interrupts simulation of current thread

– new thread is called with current value of pos

• terminated threads must have completed their memory writes

– terminate(ct) must hold

• old thread resumed with old memory position (in the activation

record)

Simulation

simulate all executions compatible with guessed memory unwinding

(43)

Basic Idea:

• every read / write is translated into a function

– simulates valid access into unwound memory

(similarly for pthread functions)

Simulation

simulate all executions compatible with guessed memory unwinding

(44)

Implementation I: Explicit Read

x y

...

z

“memory”

Guess and store sequence of individual write operations:

add

N

copies of shared variables (“memory”)

_memory[i,j] is value of j-th variable after i-th write

add array to record writes (“writes”)

i-th write is by _thr[i], which has written to _var[i]

add array to record validity of writes (“barrier”)

next write (after i) by thread t is at _next[i,t]

4 0 0 4 2 0 4 3 0 4 3 42 ... ... ... ... 0 3 42 1 2 3 4 ... W pos ... ... ... ... ... 0 0 0 1 x 1 y 2 y 1 z ... ... 2 x var thr “writes” 0 0 0 ... ... next[1] “barrier” N+1 2 4 4 ... 1 ... 3 next[T] N+1 N+1 N+1 N+1 N+1 N+1 N+1 N+1 N 3 3 N ... ... ... ... ... ... N+1

...

(45)

Simulating reads and writes

4 0 0 4 2 0 4 3 0 4 3 42 ... ... ... ... 0 3 42 x y

...

z 1 x 1 y 2 y 1 z ... ... 2 x var 1 2 3 4 ... W thr

int read(uint th, uint var) { uint th_pos;

if is_terminated(th) then return; th_pos = Jump(th_id); return (mem[th_pos][var]); } “memory” “writes” pos ... ... ... ... ... 0 0 0 0 0 0 ... ... next[1] “barrier” N+1 2 4 4 ... 1 ... 3 next[T]

...

N+1 N+1 N+1 N+1 N+1 N+1 N+1 N+1 N 3 3 N ... ... ... ... ... ... N+1

(46)

Simulating reads and writes

int write(uint th, uint var, int val) { uint jump;

if is_terminated(th) then return; jump=next[pos][th_id]; assume ( (jump<=last_write_pos) && (var[jump]==var) && (value[jump]==val) ); pos=jump; }

(47)

Other implementations

Implementation II: (Implicit Read)

mem WxV-array is replaced with W-array

var_next_write[ i ]

is smallest

j>i

s.t.

var[ i ]=var[ j ]

saves memory but causes more complex

Read implementation (larger formula)

Implementation III:

(48)

Outline

Bounded Model-checking for programs

Lazy sequentialization: Lazy-CSeq

Memory unwindings: MU-CSeq

Experiments

Conclusions

(49)

Lazy-CSeq won the Gold Medal and MU-CSeq I won the Silver Medal in the Concurrency category

– 76 concurrent C programs

UNSAFE instances: 20 programs containing a bugSAFE instances: all the others

– 4,500 l.o.c.

1) CSeq-Lazy: 1,000s, 136pts 2) CSeq-MU I: 1,200s, 136pts 3) CBMC: 29,000s, 128pts Results:

small verification times – small memory footprint – no missed bugs!

(50)

Lazy-Cseq vs Native Concurrency Handling (UNSAFE instances)

_1: timeout (750s) _2: internal error _3: manual translation not done _4: test case rejected _5: unknown failure

(51)

Evaluation: state space coverage

Lazy-CSeq + CBMC vs CBMC (SAFE instances)

How far is it possible to push the unwind bound with

the two different methods and still finish the analysis within the given time and space requirements (10GB, 750s)?

• bounding the rounds

allows deeper

exploration of loops

• alternative coverage

(52)

Evaluation: formula size

Lazy-CSeq + CBMC vs CBMC (v4.7)

(53)
(54)

Outline

Bounded Model-checking for programs

Lazy sequentialization: Lazy-CSeq

Memory unwindings: MU-CSeq

Experiments

(55)

Conclusions

LR and LMP sequentializations

complete analysis of concurrent programs up to a

given number of context-switches

(context-bounded analysis [Qadeer-Rehof, CAV’05]

unbounded analysis within each context

Lazy-CSeq and MU-CSeq use additional bounding

criteria

backend tool will bound the computations anyway

this can be exploited to induce simplifications of

the generated formula

Effective for bug-hunting

many concurrency errors show up within few

(56)

Lazy-CSeq

• Lightweight sequentialization

– designed to take advantage of modern sequ. BMC tools

– small BMC formulae for small number of rounds

– reduced memory footprint and verification times

• Laziness:

– avoid handling spurious errors typical of eager exploration – inherit from the backend tool all checks for sequential C:

array-bounds-check, division-by-zero, pointer- checks, overflow-checks, reachability of error labels and

assertion failures, etc.

(57)

MU-CSeq

• Ongoing research

• Preliminary experiments show it is competitive with

state-of-the-art model-checkers

• II improves on I on some benchmarks • III

– performs better than both I and II in general and – when it is outperfomed it stays close to the best of

the two

• NEXT: memory unwinding can be used to sequentialize

message-passing programs

(58)

Ermenegildo Tomasco

Omar Inverso

Gennaro Parlato

UK

Lazy-CSeq and MU-CSeq joint work with

Bernd Fischer

References

Related documents

Three model checking tools, called SPIN, UPPAAL and NuSMV, respectively have their own modeling language and different modeling style.. In order to compare the characteristics of

• Formal Methods in support of some aspects of safety analysis ◦ SMT solving, infinite bounded model checking,..

Previous work on deadlock detection for shared-memory multi-threaded programs includes static approaches based on type systems, dataflow analysis, or model checking, as well as

With the recent advances in the capabilities of SAT-solvers, bounded model checking (BMC)[12,13] has become a good candidate for relieving such problem in model checking

The ESST algorithm uses explicit-state model checking techniques to handle the scheduler, while analyzes the threads using symbolic techniques based on lazy predicate abstraction..

Keywords—Satisfiability Modulo Theories; Symbolic Execution; Bounded Model Checking; Automated Test Generation; Reliability Analysis; Quantitative Information Flow;..

Pseudo-Random Number Generator; PRNG; entropy loss; information flow; OpenSSL; static analysis; bounded model

As mentioned above, we illustrate SAMTools analysis functionalities by running three analysis methods on Mondex HLPN model, simulation, explicit state model checking and bounded