Abstract

Program verification is a resource-hungry task. This paper looks at the problem of parallelizing SMT-based automated program verification, specifically bounded model-checking, so that it can be distributed and executed on a cluster of machines. We present an algorithm that dynamically unfolds the call graph of the program and frequently splits it to create sub-tasks that can be solved in parallel. The algorithm is adaptive, controlling the splitting rate according to available resources, and also leverages information from the SMT solver to split where most complexity lies in the search. We implemented our algorithm by modifying Corral, the verifier used by Microsoft’s Static Driver Verifier (SDV), and evaluate it on a series of hard SDV benchmarks.

Highlights

  • Program verification has a long history of over five decades and it has been consistently challenged over this entire duration by the continued increase in the size and complexity of software

  • This paper studies the problem of automated program verification

  • We consider Bounded Model Checking (BMC) [1]: the problem of reasoning over the entire space of program inputs but only over a subset of program paths, typically up to a bound on the number of loop iterations and recursive calls

Read more

Summary

INTRODUCTION

Program verification has a long history of over five decades and it has been consistently challenged over this entire duration by the continued increase in the size and complexity of software. We aim to retain the same architecture, where we continue to use the SMT solver as a black-box, but generate multiple different VCs in parallel to search over disjoint sets of program paths. The main procedure calls multiple other procedures, each of which can manipulate global variables of the program (not shown) In this case, if we split on the call to foo, one partition (the one that must take foo) becomes trivial: it is easy to see that the assertion holds in that partition, irrespective of what happens in the rest of the program. If bar turns out to be simple, while most of the complexity lies inside baz, both partitions will end up doing the same work and diminish the benefits of parallelization In this case, we rely on extracting information from the solver (via an unsat core) to make informed splitting choices and avoid duplicating work across partitions. L10 : assume y == 3 ; return ; procedure f o o ( int x , int z ) { bool d ; L5 : goto L6 , L7 ; L6 : assume d ; assume z == x + 1 ; goto L8 ; L7 : assume ! d ; assume z == x − 1 ; goto L8 ; L8 : return ; procedure b a r ( int x , int z ) { L9 : assume z == x + 5 ; return ; Fig. 1: An Example of a Passified Program

BACKGROUND
VC generation for a single procedure
Stratified Inlining
SPLITTING THE SEARCH
Encoding splitting decisions in SI as constraints
Choosing a splitting candidate
HYDRA DESIGN AND IMPLEMENTATION
Client Design
Server Design
Adaptive rate of splitting
EXPERIMENTAL RESULTS
HYDRA versus CORRAL
Effectiveness of proof-guided splitting
Server optimizations
RELATED WORK
Full Text
Paper version not known

Talk to us

Join us for a 30 min session where you can share your feedback and ask us any queries you have

Schedule a call

Disclaimer: All third-party content on this website/platform is and will remain the property of their respective owners and is provided on "as is" basis without any warranties, express or implied. Use of third-party content does not indicate any affiliation, sponsorship with or endorsement by them. Any references to third-party content is to identify the corresponding services and shall be considered fair use under The CopyrightLaw.