ESBMC v6.0: Verifying C Programs Using kInduction and Invariant Inference
Abstract
ESBMC v6.0 employs a kinduction algorithm to both falsify and prove safety properties in C programs. We have developed a new intervalinvariant generator that preprocesses the program, inferring invariants based on intervals and introducing them in the program as assumptions. Our experiments show that ESBMC v6.0 using kinduction can prove up to 7% more programs when the invariant generation is enabled.
1 Overview
The kinduction algorithm is an effective verification technique implemented in various software model checkers with the goal of proving partial correctness over a large number of different programs and properties [1, 2, 3]. Typical kinductionbased verifiers use iterative deepening and repeatedly unwind the program to produce the verification results; its incremental nature means that it always finds the smallest falsification [2]. In SVCOMP’19, we have implemented a new intervalinvariant generator that runs as a preprocessing step in ESBMC [4]. In this implementation, invariants based on intervals are automatically introduced in the program as assumptions and, although the implementation has some limitations in keeping track of the relations between variables (i.e., our abstract domain is nonrelational), it significantly strengthens the kinduction algorithm results; in particular, we have observed that the use of invariants increases the number of correct proofs by about 7% over the SVCOMP benchmarks.
2 Verification Approach

\(I(s_n)\) and \(T(s_n, s_{n+1})\) as the formulae over program’s state variable set \(s_i\) constraining the initial states and transition relations of M;

\(\phi (s)\) as the formula encoding states satisfying a required safety property;

\(\psi (s)\) as the formula encoding states satisfying the completeness threshold, i.e. states corresponding to termination. \(\psi (s)\) will contain unwindings no deeper than the maximum number of loopiterations occurring in the program.
Note that, in our notation, termination and error are mutually exclusive: \(\phi (s) \wedge \psi (s)\) is by construction unsatisfiable; s is a deadlock state if \(T(s, s') \vee \phi (s)\) is unsatisfiable.
2.1 Invariant Inference Based on Interval Analysis
Our major new feature is a new interval invariant generator for integer variables; it computes for every integer variable a lower and an upper bound of possible values. These intervals are injected into the program as assumptions (constraints) to address a limitation of the kinduction: when trying to check S(k), the inductive step may find spurious counterexamples if the \( T^{\prime }(s_i, s_{i+1})\) overapproximation is unconstrained. This is because we havoc the variables that are written in a loop, i.e. all loop variables are assigned nondeterministic values. The effect can be seen in Eq. (3): the inductive step checks if whenever \(\phi \) holds for \(k1\) unwindings, it also holds in the current unwinding of the system. In Eq. (3), the state space is only constrained using the properties in the program; these are (usually) not strong enough to prove program correctness.
Several authors address this problem by generating program invariants to rule out unreachable regions of the state space, either as a preprocessing step where invariants are introduced in the program before verification [3], or during the verification itself [1, 5]. Similarly to Rocha et al. [3], we perform a static analysis prior to loop unwinding and (over)estimate the range that a variable can assume. In contrast to Rocha et al., we do not rely on external tools to infer polyhedral constraints (e.g., \(ax + by \le c\), where a, b, and c are constants and x and y are variables) over C programs. Instead, we implement a “rectangular” invariant generation based on interval analysis (e.g. \(a \le x \le b\)) as a preprocessing step of the verification, i.e., before the program is symbolically executed and the resulting formulae are checked by an SMT solver.
Here we use the abstractinterpretation component from CPROVER [6]. This implements an abstract domain based on expressions over intervals; these constraints associate each variable with an upper and lower bound. The algorithm starts by assuming an unbounded interval for each variable in the program and follows the reachable instructions from the main function while updates the intervals, merging them if necessary. When loops are found, an widening operation is applied, in order to accelerate the generation process [7].
3 Strengths and Weaknesses
We have observed that the use of invariants increases the number of correct proofs in ESBMC by about \(7\%\). This, however, comes at a cost: due to bugs in the invariant generator, the number of incorrect proofs is trebled if these invariants are used. In particular, we do not track intervals of variables changed through pointers and nor if the intervals are defined in terms of other variables. For this we would need a relational analysis that can keep track of relations between variables. As a result, with the interval invariants enabled, ESBMC becomes a (better) bugfinding tool rather than one delivering proofs of guaranteed soundness.
In SVCOMP’19, ESBMC correctly claims 3556 benchmarks correct and finds existing errors in 1753. Sadly, it also finds unexpected errors for 14 benchmarks and fails to find the expected errors in another 41, which impacts its overall performance. The failures are mostly concentrated in the MemSafety and ConcurrencySafety categories and are mainly due to: (1) our nonrelational abstract domain, (2) an internal bug in ESBMC (since corrected) which did not track variables going out of scope, and (3) an incomplete modelling of some pthread functions. ESBMC’s performance has improved greatly since SVCOMP’18 (v4.60): the number of errors detected has increased by \(36\%\) and the number of correcttrue results increased by \(32\%\). The biggest improvements are reflected in the categories ReachSafety and FalsificationOverall.
4 Tool Setup and Configuration
where a sets the architecture, p sets the property file path, and s sets the strategy, in this case, kinduction for kinduction.
Internally, by choosing the kinduction strategy, the following options are set for every property when executing ESBMCkind: nodivbyzerocheck, which disables the division by zero check (required by SVCOMP); kinduction, which enables the kinduction; floatbv, which enables floatingpoint SMT encoding; unlimitedksteps, which removes the upper limit of iteration steps in the kinduction algorithm; witnessoutput, which sets the witness output path; forcemallocsuccess, which sets that all dynamic allocations succeed (also an SVCOMP requirement); and intervalanalysis, which enables the invariant generation. In addition, ESBMCkind sets further options depending on the property that needs to be checked: nopointercheck and noboundscheck for reachability verification; memoryleakcheck for memory verification; and overflowcheck for overflow verification. The Benchexec tool info module is named esbmc.py and the benchmark definition file is esbmckind.xml. For SVCOMP’19, ESBMCkind uses Boolector v2.4.1 [8] and competes in all categories with C programs.
5 Software Project
The ESBMC source code is available for downloading at https://github.com/esbmc/esbmc, while selfcontained binaries for ESBMC v6.0 64bit can be downloaded from https://github.com/esbmc/esbmc/releases. ESBMC is publicly available under the terms of the Apache License 2.0. Instructions for building ESBMC from source are given in the file BUILDING (including the description of all dependencies). ESBMC is a joint project with the Federal University of Amazonas (Brazil), University of Southampton (UK), University of Manchester (UK), and University of Stellenbosch (South Africa).
Footnotes
References
 1.Beyer, D., Dangl, M., Wendler, P.: Boosting kinduction with continuouslyrefined invariants. In: Kroening, D., Păsăreanu, C.S. (eds.) CAV 2015. LNCS, vol. 9206, pp. 622–640. Springer, Cham (2015). https://doi.org/10.1007/9783319216904_42CrossRefGoogle Scholar
 2.Gadelha, M.Y.R., Ismail, H.I., Cordeiro, L.C.: Handling loops in bounded model checking of C programs via \(k\)induction. STTT 19(1), 97–114 (2017)CrossRefGoogle Scholar
 3.Rocha, W., Rocha, H., Ismail, H., Cordeiro, L., Fischer, B.: DepthK: a kinduction verifier based on invariant inference for C programs. In: Legay, A., Margaria, T. (eds.) TACAS 2017. LNCS, vol. 10206, pp. 360–364. Springer, Heidelberg (2017). https://doi.org/10.1007/9783662545805_23CrossRefGoogle Scholar
 4.Gadelha, M.R., Monteiro, F.R., Morse, J., Cordeiro, L.C., Fischer, B., Nicole, D.A.: ESBMC 5.0: an industrialstrength C model checker. In: ASE, pp. 888–891. IEEE/ACM (2018)Google Scholar
 5.Malík, V., Martiček, Š., Schrammel, P., Srivas, M., Vojnar, T., Wahlang, J.: 2LS: memory safety and nontermination. In: Beyer, D., Huisman, M. (eds.) TACAS 2018. LNCS, vol. 10806, pp. 417–421. Springer, Cham (2018). https://doi.org/10.1007/9783319899633_24CrossRefGoogle Scholar
 6.Kroening, D.: CProver Manual (2018). http://www.cprover.org/cprovermanual/. Accessed Feb 2019
 7.Yamaguchi, T., Brain, M., Ryder, C., Imai, Y., Kawamura, Y.: Application of abstract interpretation to the automotive electronic control system. In: Enea, C., Piskac, R. (eds.) VMCAI 2019. LNCS, vol. 11388, pp. 425–445. Springer, Cham (2019). https://doi.org/10.1007/9783030112455_20CrossRefGoogle Scholar
 8.Niemetz, A., Preiner, M., Biere, A.: Boolector 2.0 system description. J. Satisfiability Boolean Model. Comput. 9, 53–58 (2015)Google Scholar
Copyright information
Open Access This chapter is licensed under the terms of the Creative Commons Attribution 4.0 International License (http://creativecommons.org/licenses/by/4.0/), which permits use, sharing, adaptation, distribution and reproduction in any medium or format, as long as you give appropriate credit to the original author(s) and the source, provide a link to the Creative Commons license and indicate if changes were made.
The images or other third party material in this chapter are included in the chapter's Creative Commons license, unless indicated otherwise in a credit line to the material. If material is not included in the chapter's Creative Commons license and your intended use is not permitted by statutory regulation or exceeds the permitted use, you will need to obtain permission directly from the copyright holder.