Abstract
VeriAbs verifies C programs by transforming them to abstract programs. The transformation replaces loops in the original code by abstract loops of small known bounds. Bounded model checkers can then be used to prove properties over such programs. To perform such a transformation, VeriAbs implements (i) a static value analysis to compute loop invariants, (ii) abstract acceleration and output abstraction for numerical loops, (iii) a novel array witness selection for loops that iterate over arrays, and (iv) an iterative refinement using an enhanced k-induction technique. To find errors, VeriAbs computes bounds of the original loops and then checks for errors within those bounds. VeriAbs can thus prove properties and find errors using bounded model checking. It uses the C Bounded Model Checker (CBMC) version 5.4 with MiniSat version 2.2.
P. Darke—Jury member.
You have full access to this open access chapter, Download conference paper PDF
1 Verification Approach
Bounded model checking [3] verifies programs up to a finite execution length. Hence it can find errors effectively but not prove properties. To overcome this limitation, we present a tool called VeriAbs that implements a loop abstraction technique to transform a source C program to an abstract program called a target. By this, loops in the source are replaced with abstract loops of small known bounds in the target. Due to the known bounds of the abstract loops, the target has a finite execution length and bounded model checking can then prove properties over this program. The following two techniques are applied to abstract loops in the source:
Numerical Loop Abstraction. VeriAbs abstracts a loop by over-approximating the values of numerical variables modified by that loop [5]. The variables modified by a loop are called output variables and are classified as (i) input-output (IO) - variables that are read and modified in the loop body, and (ii) pure output (PO) - variables that are modified but never read in the loop body. We explain the abstraction of outputs as follows.
The IO variables are abstracted using abstract acceleration [5] which captures the effect of several loop iterations. It comprises of assignments to all IO variables using closed form expressions, like those computed for recurrence relations. This generates an abstraction of the IO variables at the start of a non-deterministically chosen \(k^{th}\) iteration of the loop. VeriAbs then executes the loop body to generate an abstraction of the IO variables at the end of the \(k^{th}\) iteration. A pure output on the other hand cannot be accelerated, as it is never read in the loop body but only modified through assignments. So to abstract one pure output, VeriAbs non-deterministically selects and executes an iteration that assigns to the pure output. Before executing this iteration VeriAbs applies abstract acceleration to the IO variables. Executing the loop body in this manner abstracts the pure output because all variables controlling the execution of the assignment to the pure output or read in the assignment to the pure output were abstracted using acceleration. So to abstract all outputs of a loop, VeriAbs applies abstract acceleration followed by loop body execution, then repeats this as many times as the number of pure outputs. This generates an abstract loop of a known small bound.
To improve precision, VeriAbs applies induction whenever the input property lies within the loop [5]. The base case of the induction consists of the original loop body with the property check; and the induction step consists of the abstract loop assuming the property holds (the induction hypothesis), followed by the original loop body with the property check. VeriAbs extends this to incremental k-induction in order to refine the abstraction as explained in Sect. 1.1. VeriAbs for the first time implements k-induction wherein the induction hypothesis is generated using numerical loop abstraction. This technique can lead to a better precision than others which only assign non-deterministic values to the outputs in the hypothesis. VeriAbs also generates loop invariants using a light weight value analysis [8]. These invariants are further strengthened by loop abstraction and k-induction.
Array Loop Abstraction. The abstraction differs for loops that process arrays of large or unknown sizes [9]. In such cases, the abstraction over-approximates the behavior of the original program by substituting the loop with an abstract loop that executes over a small non-deterministically chosen sequence of array elements. We call this chosen sequence as a witness sequence of the original loop. The witness sequence guides the abstract loop to execute iterations that correspond to specific iterations of the original loop. This abstraction ensures that if the program is incorrect, the abstract program will also be incorrect and the same will be demonstrated by some witness sequence. The size of witness sequence depends on the input property and loop body characteristics.
1.1 Verification Process
VeriAbs accepts C code with user defined properties and outputs its verification result as successful (if all properties hold), failure (if any property fails), or unknown (if any property is unresolved). For this, VeriAbs first transforms the source to generate a target with abstract arrays and loops of known small bounds. Since the target is an over-approximation of the source, if the property holds in the target, it holds in the source as well. VeriAbs verifies the input property using the following steps:
-
Step 1: It passes the target to a bounded model checker while ensuring that each loop in the target is unrolled up to its known small bound. So if the model checker proves the property, VeriAbs reports the verification status as successful. If it generates a counter example due to over-approximation, Step 2 is executed.
-
Step 2: In this step, VeriAbs computes bounds of loops which have a constant number of iterations in the source. For this it uses a light weight value analysis [8]. Then the source along with these bounds are passed to the bounded model checker while ensuring that the model checker is inconclusive if any loop is not unrolled up to its maximum bound. Accordingly, VeriAbs reports the verification status if the model checker is able to (in)validate the property. If the model checker is inconclusive due to loops of unknown or infinite bounds, Step 3 is executed.
-
Step 3: In this step, VeriAbs iteratively refines the target by incrementally applying k-induction to the loops in which the input property lies. k-induction implemented by VeriAbs consists of k base cases of the original loop followed by the induction step as explained in Sect. 1. In each refinement iteration, VeriAbs generates a target with an incremented value of k starting from 2. It then passes this abstraction to the bounded model checker while ensuring that each abstract loop is unrolled up to its known bound. Thus VeriAbs reports the verification status as successful if the model checker proves the property. Otherwise it continues to refine the target till the property is proved or k reaches a threshold value of 150 (chosen heuristically) and the property remains unresolved.
VeriAbs generates safety witnesses from the target, and violation witnesses from the source using an off-the-shelf witness generator.
2 Software Architecture
Figure 1 shows the architecture of VeriAbs. It implements a static analysis in Java to perform loop and array abstraction, compute loop bounds, and generate target code. It uses a program analysis framework called PRISM [7] to implement this analysis. It implements iterative refinement in Java and Perl. It uses the C Bounded Model Checker (CBMC) version 5.4 [4] with a SAT solver, MiniSat version 2.2 [6]. It uses CPAchecker version 1.6.1 [2] for generating witnesses in the graphml format.
3 Strengths and Weaknesses
The main strength of VeriAbs is that it is sound. All transformations implemented by the tool are abstractions and hence if the tool reports that a property holds then it indeed holds. Another key strength is that it transforms all loops in a program to abstract loops with a known finite number of iterations, enabling the use of bounded model checkers for property proving. The main weakness of the tool is that it does not implement a refinement process that is well suited to find errors. VeriAbs uses bounded model checkers directly to find errors by unrolling loops a small finite number of times.
4 Tool Setup and Configuration
The VeriAbs executable for SV-COMP 2017 is available for download at the URL http://115.113.148.49/VeriAbs.htm. To install the tool, download the archive, extract its contents, and follow the installation instructions in VeriAbs/INSTALL.txt. To execute VeriAbs, the user needs to specify the property file of the respective verification category using the property-file option. The witness is generated in the current working directory as witness.graphml. A sample command is as follows:
VeriAbs executes CBMC with the unwinding-assertions option to ensure soundness. It is participating in the Arrays, ControlFlow, ECA, Loops, ProductLines, Recursive and Sequentialized sub-categories of the ReachSafety category.
5 Software Project and Contributors
VeriAbs and the PRISM program analysis framework are maintained by TCS Research [1]. VeriAbs has been developed by Bharti Chimdyalwar, Priyanka Darke, Avriti Chauhan and Punit Shah under the guidance of R Venkatesh and Shrawan Kumar. We would like to thank graduate and under-graduate interns who have contributed to the development of the numerical loop abstraction module in VeriAbs.
References
TCS Research. http://www.tcs.com/research/Pages/default.aspx
Beyer, D., Erkan Keremoglu, M.: CPAchecker: a tool for configurable software verification. CoRR, abs/0902.0019 (2009)
Biere, A., Cimatti, A., Clarke, E., Zhu, Y.: Symbolic model checking without BDDs. In: Cleaveland, W.R. (ed.) TACAS 1999. LNCS, vol. 1579, pp. 193–207. Springer, Heidelberg (1999). doi:10.1007/3-540-49059-0_14
Clarke, E., Kroening, D., Lerda, F.: A tool for checking ANSI-C programs. In: Jensen, K., Podelski, A. (eds.) TACAS 2004. LNCS, vol. 2988, pp. 168–176. Springer, Heidelberg (2004). doi:10.1007/978-3-540-24730-2_15
Darke, P., Chimdyalwar, B., Venkatesh, R., Shrotri, U., Metta, R.: Over-approximating loops to prove properties using bounded model checking. In: DATE 2015, Grenoble, France, 9–13 March 2015, pp. 1407–1412. IEEE (2015)
Eén, N., Sörensson, N.: An extensible SAT-solver. In: Giunchiglia, E., Tacchella, A. (eds.) SAT 2003. LNCS, vol. 2919, pp. 502–518. Springer, Heidelberg (2004). doi:10.1007/978-3-540-24605-3_37
Khare, S., Saraswat, S., Kumar, S.: Static program analysis of large embedded code base: an experience. In: ISEC, pp. 99–102. ACM (2011)
Kumar, S., Chimdyalwar, B., Shrotri, U.: Precise range analysis on large industry code. In: ESEC/FSE 2013, pp. 675–678 (2013)
Kumar, S., Sanyal, A., Venkatesh, R., Shah, P.: Property checking array programs using witness sequences. TCS Internal Technical report (2016)
Author information
Authors and Affiliations
Corresponding author
Editor information
Editors and Affiliations
Rights and permissions
Copyright information
© 2017 Springer-Verlag GmbH Germany
About this paper
Cite this paper
Chimdyalwar, B., Darke, P., Chauhan, A., Shah, P., Kumar, S., Venkatesh, R. (2017). VeriAbs: Verification by Abstraction (Competition Contribution). In: Legay, A., Margaria, T. (eds) Tools and Algorithms for the Construction and Analysis of Systems. TACAS 2017. Lecture Notes in Computer Science(), vol 10206. Springer, Berlin, Heidelberg. https://doi.org/10.1007/978-3-662-54580-5_32
Download citation
DOI: https://doi.org/10.1007/978-3-662-54580-5_32
Published:
Publisher Name: Springer, Berlin, Heidelberg
Print ISBN: 978-3-662-54579-9
Online ISBN: 978-3-662-54580-5
eBook Packages: Computer ScienceComputer Science (R0)