bounded model checking of multi-threaded c programs via lazy sequentialization omar inverso...
DESCRIPTION
BMC approach - Sequential C Programs tools BLITZ [ Cho, D'Silva, Song – ASE’13 ] CBMC [ Clarke, Kroening, Lerda – TACAS’04 ] LLBMC [ Falke, Merz, Sinz – ASE’13 ] ESBMC [ Cordeiro, Fischer, Marques-Silva – ASE’09 ] PROGRAM BOUNDED PROGRAM SAT/SMT FORMULA SOLVER inlining unrolling SSA formTRANSCRIPT
Bounded Model Checkingof
Multi-Threaded C Programsvia
Lazy Sequentialization
Omar Inverso University of Southampton, UK
Ermenegildo Tomasco University of Southampton, UK
Bernd Fischer Stellenbosch University, South Africa
Salvatore La Torre Università di Salerno, Italy
Gennaro Parlato University of Southampton, UK
Concurrent Programs - Reachability Problem
concurrent C programs• POSIX threads• SC memory model
reachability• assertion failure• out-of-bound array• division-by-zero, …
bounded model checking (BMC)• bug-finding, not complete analysis
SHARED MEMORY
…T1 T2
TN
THREADS
BMC approach - Sequential C Programs
tools• BLITZ [ Cho, D'Silva, Song – ASE’13 ]• CBMC [ Clarke, Kroening, Lerda – TACAS’04 ] • LLBMC [ Falke, Merz, Sinz – ASE’13 ]• ESBMC [ Cordeiro, Fischer, Marques-Silva – ASE’09 ]
PROGRAM BOUNDEDPROGRAM
SAT/SMTFORMULA
SOLVER
inliningunrollingSSA form
direct SAT/SMT approach• encode each thread as in the sequential case • add a conjunct for shared memory operations• all possible interleavings in the bounded program
φthreads ∧ φconcurrency
papers:• [ Sinha, Wang – POPL’11 ]• [ Alglave, Kroening, Tautschnig – CAV’13 ]
BMC approach - Concurrent C Programs
CONCPROGRAM
BOUNDEDPROGRAM
SAT/SMTFORMULA
SOLVER
concurrencyhandling
Sequentialization
pros• reuse robust sequential analysis tools• fast prototyping of concurrency handling
• delegating all sequential reasoning to an existing target analysis tool
• easier to implement than full-fledged tools
CONCPROGRAM
BOUNDEDPROGRAM
SAT/SMTFORMULA
SOLVER
SEQPROGRAM
SEQ TOOL
SEQ
UEN
TIA
LIZA
TIO
N(c
ode-
to-c
ode
trans
latio
n)
SEQ
UEN
TIA
LIZA
TIO
N(c
ode-
to-c
ode
trans
latio
n)
Sequentialization
papers
• proposal [ Qadeer, Wu – PLDI’04 ]• eager, bounded context-switch, finite # threads [ Lal, Reps – CAV’08 ]• lazy, finite # threads, parameterized [La Torre, Madhusudan, Parlato – CAV’09, CAV’10]• thread creation [Bouajjani, Emmi, Parlato – SAS’11] [Emmi, Qadeer, Rakamaric – POPL’11]• Lal/Reps for real-time systems [Chaki, Gurfinkel, Strichman – FMCAD’11]• message-passing programs [Bouajjani, Emmi -- TACAS’12]
CONCPROGRAM
BOUNDEDPROGRAM
SAT/SMTFORMULA
SOLVER
SEQPROGRAM
SEQ TOOL
SEQ
UEN
TIA
LIZA
TIO
N(c
ode-
to-c
ode
trans
latio
n)
Sequentialization
tools (Implementations of variants of Lal/Reps schema)
• Corral [ Lal, Qadeer, Lahiri – CAV’12 ]
• CSeq [ Fischer, Inverso, Parlato – ASE’13 ]
• Rek [ Chaki, Gurfinkel, Strichman – FMCAD’11 ]
• STORM [ Lahiri,Qadeer,Rakamaric CAV’09 ]
CONCPROGRAM
BOUNDEDPROGRAM
SAT/SMTFORMULA
SOLVER
SEQPROGRAM
SEQ TOOL
BMC based
Sequentialization
what we propose new sequentialization targeting BMC efficient + surprisingly simple
CONCPROGRAM
BOUNDEDPROGRAM
SAT/SMTFORMULA
SOLVER
SEQPROGRAM
SEQ TOOL
SEQ
UEN
TIA
LIZA
TIO
N(c
ode-
to-c
ode
trans
latio
n)
Lazy-CSeq: Schema Overview(new sequentialization for BMC)
Lazy-CSeq Approach
BOUNDEDPROGRAM
BMC SEQUENTIAL
TOOL
SEQPROGRAM
SEQ
UEN
TIA
LIZA
TIO
N(c
ode-
to-c
ode
trans
latio
n) CONCPROGRAM
Bounded Concurrent Programs
main()T0 TNTN-1T1 …
• no loops• no function calls• Control flow only forward• one procedure for each thread
Round Robin Schedule
main()T0 TNTN-1T1
…
Lazy-Cseq sequentialization:• captures all bounded Round-Robin computations for a given bound• error manifest themselves within very few rounds [ Musuvathi, Qadeer – PLDI’07 ]
round 1
round 2
round k
round 3
Schema Overview
…main()T0 T1
TN
…F0 F1
FN main()
bounded concurrent program
sequential program
Sequentialization(code-to-code translation)
Sequentialized functions Driver
translates
…
translates
translates
Naïve Lazy Sequentialization: CROSS PRODUCT SIMULATION
pc0=0; ... pcN=0;local0; ... localk;
main() { for (r=0; r<K; r++) for (i=0; i<N; i++) // simulate Ti
if (activei)
Fi();}
main driver• a global pc for each thread • thread locals thread global
Naïve Lazy Sequentialization: CROSS PRODUCT SIMULATION
pc0=0; ... pcN=0;local0; ... localk;
main() { for (r=0; r<K; r++) for (i=0; i<N; i++) // simulate Ti
if (activei)
Fi();}
main driver for each round
for each thread Ti
simulate Ti
Naïve Lazy Sequentialization: CROSS PRODUCT SIMULATION
pc0=0; ... pcN=0;local0; ... localk;
main() { for (r=0; r<K; r++) for (i=0; i<N; i++) // simulate Ti
if (activei)
Fi();}
switch(pck) { case 0: goto 0; case 1: goto 1; case 2: goto 2;
... case M: goto M;}
1: CS(0); stmt0;2: CS(1); stmt1;3: CS(2); stmt2; . . . E XE . . .M: CS(M); stmtM;
main driver
Fi()
Naïve Lazy Sequentialization: CROSS PRODUCT SIMULATION
pc0=0; ... pcN=0;local0; ... localk;
main() { for (r=0; r<K; r++) for (i=0; i<N; i++) // simulate Ti
if (activei)
Fi();}
switch(pck) { case 0: goto 0; case 1: goto 1; case 2: goto 2;
... case M: goto M;}
1: CS(0); stmt0;2: CS(1); stmt1;3: CS(2); stmt2; . . . E XE . . .M: CS(M); stmtM;
main driver
Fi()
... ...
context-switch
resume m
echanism
Naïve Lazy Sequentialization: CROSS PRODUCT SIMULATION
pc0=0; ... pcN=0;local0; ... localk;
main() { for (r=0; r<K; r++) for (i=0; i<N; i++) // simulate Ti
if (activei)
Fi();}
switch(pck) { case 0: goto 0; case 1: goto 1; case 2: goto 2;
... case M: goto M;}
1: CS(0); stmt0;2: CS(1); stmt1;3: CS(2); stmt2; . . . E XE . . .M: CS(M); stmtM;
main driver
Fi() ...
... ...
Context-switch simulation: #define CS(j) if (*) { pci=j; return; }
Naïve Lazy Sequentialization: CROSS PRODUCT SIMULATION
pc0=0; ... pcN=0;local0; ... localk;
main() { for (r=0; r<K; r++) for (i=0; i<N; i++) // simulate Ti
if (activei)
Fi();}
switch(pck) { case 0: goto 0; case 1: goto 1; case 2: goto 2;
... case M: goto M;}
1: CS(0); stmt0;2: CS(1); stmt1;3: CS(2); stmt2; . . . E XE . . .M: CS(M); stmtM;
main driver
Fi() ...
... ...
Naïve Lazy Sequentialization: CROSS PRODUCT SIMULATION
pc0=0; pc1=0; ... pcN=0;local0; local1; ... localk;
main() { for (r=0; r<R; r++) for (k=0; k<N; k++) // simulate Tk
Fk();}
switch(pck) { case 0: goto 0; case 1: goto 1; case 2: goto 2;
... case M: goto M;}
1: CS(0); stmt0;2: CS(1); stmt1;3: CS(2); stmt2; . . . E XE . . .M: CS(M); stmtM;
main driver
...
... ...
Formula encoding:
goto statement to formula
add a guard for each crossing control-flow edge
= O(M2) guards
pc0=0; ... pcN=0;local0; ... localk;
main() { for (r=0; r<K; r++) for (i=0; i<N; i++) // simulate Ti
if (activei) Fi();}
switch(pck) { case 0: goto 0; case 1: goto 1; case 2: goto 2;
... case M: goto M;}
1: CS(0); stmt0;2: CS(1); stmt1;3: CS(2); stmt2; . . . E XE . . .M: CS(M); stmtM;
main driver
Fi() ...
... ...
CSeq-Lazy Sequentialization: CROSS PRODUCT SIMULATION
pc0=0; ... pcN=0;local0; ... localk;
main() { for (r=0; r<K; r++) for (i=0; i<N; i++) // simulate Ti
if (activei) Fi();}
switch(pck) { case 0: goto 0; case 1: goto 1; case 2: goto 2;
... case M: goto M;}
1: CS(0); stmt0;2: CS(1); stmt1;3: CS(2); stmt2; . . . E XE . . .M: CS(M); stmtM;
main driver
Fi() ...
... ...
CSeq-Lazy Sequentialization: CROSS PRODUCT SIMULATION
pc0=0; ... pcN=0; local0; ... localk;
main() { for (r=0; r<K; r++) for (i=0; i<N; i++) // simulate Ti
if (activei) Fi();}
switch(pck) { case 0: goto 0; case 1: goto 1; case 2: goto 2;
... case M: goto M;}
1: CS(0); stmt0;2: CS(1); stmt1;3: CS(2); stmt2; . . . E XE . . .M: CS(M); stmtM;
main driver
Fi() ...
CSeq-Lazy Sequentialization: CROSS PRODUCT SIMULATION
switch(pck) { case 0: goto 0; case 1: goto 1; case 2: goto 2;
... case M: goto M;}
1: CS(0); stmt0;2: CS(1); stmt1;3: CS(2); stmt2; . . . E XE . . .M: CS(M); stmtM;
main driver
Fi() ...
CSeq-Lazy Sequentialization: CROSS PRODUCT SIMULATION
#define CS(j) NEW if (j<pci || j>=nextCS) goto j+1;
pc0=0; ... pcN=0; local0; ... localk;nextCS;main() for (r=0; r<K; r++) for (i=0; i<N; i++) // simulate Ti
if (activei) nextCS = nondet; assume(nextCS>=pci) Fi(); pci = nextCS;
switch(pck) { case 0: goto 0; case 1: goto 1; case 2: goto 2;
... case M: goto M;}
1: CS(0); stmt0;2: CS(1); stmt1;3: CS(2); stmt2; . . . E XE . . .M: CS(M); stmtM;
main driver
Fi()
CSeq-Lazy Sequentialization: CROSS PRODUCT SIMULATION
#define CS(j) NEW if (j<pci || j>=nextCS) goto j+1;
pc0=0; ... pcN=0; local0; ... localk;nextCS;main() for (r=0; r<K; r++) for (i=0; i<N; i++) // simulate Ti
if (activei) nextCS = nondet; assume(nextCS>=pci) Fi(); pci = nextCS;
switch(pck) { case 0: goto 0; case 1: goto 1; case 2: goto 2;
... case M: goto M;}
1: CS(0); stmt0;2: CS(1); stmt1;3: CS(2); stmt2; . . . E XE . . .M: CS(M); stmtM;
main driver
Fi()
CSeq-Lazy Sequentialization: CROSS PRODUCT SIMULATION
#define CS(j) NEW if (j<pci || j>=nextCS) goto j+1;
...
pc0=0; ... pcN=0; local0; ... localk;nextCS;main() for (r=0; r<K; r++) for (i=0; i<N; i++) // simulate Ti
if (activei) nextCS = nondet; assume(nextCS>=pci) Fi(); pci = nextCS;
resuming + context-switch
1: CS(1); stmt1;2: CS(2); stmt2;3: CS(3); stmt3;
EXECUTE
M: CS(M); stmtM;
nextCS
...
skip
pci
...
skip
#define CS(j) NEW if (j<pci || j>=nextCS) goto j+1;
CSeq-Lazy Sequentialization: CROSS PRODUCT SIMULATION
Individual Threads Sequentialization
1: CS(1); stmt1;2: CS(2); stmt2;3: CS(3); stmt3;
EXECUTE
M: CS(M); stmtM;
...
...
Formula encoding:
goto statement to formula
add a guard for each crossing control-flow edge
= O(M) guards
Individual Threads Sequentialization
1: CS(1); stmt1;2: CS(2); stmt2;3: CS(3); stmt3;
EXECUTE
M: CS(M); stmtM;
...
...
#define CS(j) if (j<pci || j>=next_CS) goto pc+1;
inject light-weight, non-invasive control code
• no non-determinism• no assignments• o return
Tool / Empirical Evaluation
Tool: CSeq
sequentialnon-deterministic
C program
P'
concurrentC program
P
true/falseCSeqsequential
BMCCBMC, ESBMC, LLBMC
rounds backendunwind
[ Fischer, Inverso, Parlato -- ASE’13 ]
Evaluation: bug-huntingSVCOMP’14, Concurrency (UNSAFE instances)
Lazy-CSeq Concurrent Tools
U R BLITZ
CBMC
ESBMC
LLBMC CBMC
ESBMC Corral CSeq
Threader
27_Boop_simple_vf 2 2 0.3 0.3 0.8 0.4 0.4 TO 1.9 1.0 117.628_buggy_simple_... 2 1 0.2 0.2 0.3 0.3 0.3 624.7 0.8 0.2 0.332_pthread5_vs 2 2 0.4 0.3 0.2 0.2 0.8 TO 2.2 n/a TO40_barrier_vf 4 1 0.2 0.2 0.3 0.3 0.6 n/a 0.8 n/a 0.749_bigshot_p 1 2 0.3 0.3 0.3 0.6 0.3 1.7 n/a n/a n/a50_bigshot_s 1 2 0.3 0.3 0.3 0.6 0.5 4.0 n/a n/a n/a53_fib_bench 5 5 36.6 1.0 15.2 2.1 1.8 31.1 5.8 6.3 6.955_fib_bench_longer 6 6 155.5 1.5 402.1 3.1 3.2 150.9 14.4 7.2 10.4
57_fib_bench_longest 11 11 TO 214.0 TO TO 75.2 TO TO n/a 54.3
61_lazy01 1 1 0.3 0.2 0.2 0.4 0.5 398.6 1.3 0.7 7.163_qrcu 1 2 1.4 0.8 0.7 safe 0.7 TO 5.8 safe TO65_queue 2 2 1.6 8.8 1.1 TO 20.9 TO n/a 128.7 n/a67_read_write_lock 1 2 0.5 0.3 0.4 safe 0.4 TO 1.8 2.6 38.469_reorder_2 2 1 0.3 0.6 n/a 1.3 0.7 TO 1.3 n/a 2.470_reorder_5 4 1 0.4 0.9 n/a 3.3 0.7 TO 1.9 n/a 3.572_sigma 16 1 1.4 7.8 n/a 73.0 219.1 TO n/a n/a n/a73_singleton 1 3 0.7 0.5 0.5 safe 1.6 TO n/a n/a n/a75_stack 2 1 0.2 0.3 0.3 1.0 0.8 TO 2.1 2.1 151.977_stateful01 1 1 0.2 0.2 0.3 0.5 0.7 TO 2.0 0.7 0.982_twostage_3 2 1 0.3 0.8 n/a 8.0 4.9 TO 3.6 n/a TO
Evaluation: bug-huntingSVCOMP’14, Concurrency (UNSAFE instances)
Lazy-CSeq Concurrent Tools
U R BLITZ
CBMC
ESBMC
LLBMC CBMC
ESBMC Corral CSeq
Threader
27_Boop_simple_vf 2 2 0.3 0.3 0.8 0.4 0.4 TO 1.9 1.0 117.628_buggy_simple_... 2 1 0.2 0.2 0.3 0.3 0.3 624.7 0.8 0.2 0.332_pthread5_vs 2 2 0.4 0.3 0.2 0.2 0.8 TO 2.2 n/a TO40_barrier_vf 4 1 0.2 0.2 0.3 0.3 0.6 n/a 0.8 n/a 0.749_bigshot_p 1 2 0.3 0.3 0.3 0.6 0.3 1.7 n/a n/a n/a50_bigshot_s 1 2 0.3 0.3 0.3 0.6 0.5 4.0 n/a n/a n/a53_fib_bench 5 5 36.6 1.0 15.2 2.1 1.8 31.1 5.8 6.3 6.955_fib_bench_longer 6 6 155.5 1.5 402.1 3.1 3.2 150.9 14.4 7.2 10.4
57_fib_bench_longest 11 11 TO 214.0 TO TO 75.2 TO TO n/a 54.3
61_lazy01 1 1 0.3 0.2 0.2 0.4 0.5 398.6 1.3 0.7 7.163_qrcu 1 2 1.4 0.8 0.7 safe 0.7 TO 5.8 safe TO65_queue 2 2 1.6 8.8 1.1 TO 20.9 TO n/a 128.7 n/a67_read_write_lock 1 2 0.5 0.3 0.4 safe 0.4 TO 1.8 2.6 38.469_reorder_2 2 1 0.3 0.6 n/a 1.3 0.7 TO 1.3 n/a 2.470_reorder_5 4 1 0.4 0.9 n/a 3.3 0.7 TO 1.9 n/a 3.572_sigma 16 1 1.4 7.8 n/a 73.0 219.1 TO n/a n/a n/a73_singleton 1 3 0.7 0.5 0.5 safe 1.6 TO n/a n/a n/a75_stack 2 1 0.2 0.3 0.3 1.0 0.8 TO 2.1 2.1 151.977_stateful01 1 1 0.2 0.2 0.3 0.5 0.7 TO 2.0 0.7 0.982_twostage_3 2 1 0.3 0.8 n/a 8.0 4.9 TO 3.6 n/a TO
Conclusions
Conclusions / Future Work
We have presented a new sequentialization targeted to BMC backends• lazy• based on bounded round-robin computations• efficient for bug-hunting• simple to implement (CSeq framework)
Eager vs Lazy• no empirical evidence that lazy is faster (maybe faster because of good handing of CFG) • Lazy does not require an implementation of memory model and handling of error checks
Lazy-CSeq won the gold medal in the Concurrency category of SVCOMP’14• all verification tasks solved• 30x faster than the best tool with native concurrency handling
Future Work• integration with partial order reduction• Weak Memory Models (WMM)• Message Passing Interface (MPI)• sequentializations targeting other analysis technologies:
• abstract interpretation• cegar-based• testing
Thank You
users.ecs.soton.ac.uk/gp4/cseq
Evaluation: state space coverage
Lazy-CSeq + CBMC vs CBMC (SAFE instances)
How far is it possible to push the unwind bound withthe two different methods and still finish the analysis withinthe given time and space requirements (10GB, 750s)?
• CBMC starts failing >60% files when increasing unwind bound
• bounding the rounds allows deeper exploration of loops
• alternative coverage of the state space
Evaluation: formula size
Lazy-CSeq + CBMC vs CBMC (SAFE instances)
What is the VC size for sequentialized files compared to native concurrency handling?
• 5x..15x less variables• 5x..25x less clauses