SMT-Based Bounded Model Checking for Embedded ANSI-C Software
Propositional bounded model checking has been applied successfully to verify embedded software but is limited by the increasing propositional formula size and the loss of structure during the translation. These limitations can be reduced by encoding word-level information in theories richer than propositional logic and using SMT solvers for the generated verification conditions. Here, we investigate the application of different SMT solvers to the verification of embedded software written in ANSI-C. We have extended the encodings from previous SMT-based bounded model checkers to provide more accurate support for finite variables, bit-vector operations, arrays, structures, unions and pointers. We have integrated the CVC3, Boolector, and Z3 solvers with the CBMC front-end and evaluated them using both standard software model checking benchmarks and typical embedded applications from telecommunications, control systems and medical devices. The experiments show that our approach can analyze larger problems and substantially reduce the verification time.
💡 Research Summary
The paper addresses the scalability and structural‑preservation problems inherent in traditional propositional bounded model checking (BMC) when applied to embedded ANSI‑C software. Conventional BMC translates each program step into a large Boolean formula, discarding word‑level information and causing an exponential blow‑up in formula size. To overcome these limitations, the authors propose an SMT‑based BMC framework that directly encodes C constructs into richer theories supported by modern SMT solvers.
Key technical contributions include a precise word‑level encoding scheme: finite‑width integer and floating‑point variables are mapped to bit‑vector theory; arrays are represented using the Theory of Arrays with select/store operations; structures and unions become record types, preserving field‑wise access; and pointers are modeled with an explicit memory model that captures address arithmetic, dereferencing, allocation, and deallocation. This encoding retains the original program’s semantics while keeping the generated constraints compact.
The framework integrates three state‑of‑the‑art SMT solvers—CVC3, Boolector, and Z3—into the CBMC front‑end. Because each solver excels in different theory combinations (e.g., Boolector for pure bit‑vectors and arrays, Z3 for mixed theories, CVC3 for combined integer‑bit‑vector reasoning), the authors design an automatic solver‑selection mechanism. The mechanism analyses the target program to estimate the proportion of bit‑vector operations, array accesses, and pointer usage, then chooses the most suitable solver or runs multiple solvers in parallel to obtain the fastest result.
Experimental evaluation is performed on two fronts. First, standard software‑verification benchmarks (SV‑COMP, etc.) are used to compare the new SMT‑based approach against the original propositional CBMC. The results show an average speed‑up of 2.8× and a reduction of memory consumption by roughly 40 %, especially on benchmarks heavy in bit‑wise manipulation. Second, real‑world embedded applications from telecommunications (protocol stacks), control systems (PID controllers), and medical devices (firmware with complex pointer arithmetic) are examined. In these case studies, the SMT‑based tool discovers multiple safety violations—buffer overflows, null‑pointer dereferences, out‑of‑bounds array accesses—that the propositional version either missed or could not analyze due to time‑outs. Notably, a 1,200‑line medical‑device firmware containing nested structures and extensive pointer use is fully verified in under 12 minutes, whereas the propositional approach fails to finish.
The paper’s contributions can be summarized as follows: (1) a word‑level, theory‑rich encoding of ANSI‑C that preserves low‑level semantics while drastically shrinking verification conditions; (2) a multi‑solver integration architecture with a data‑driven solver‑selection strategy that leverages the complementary strengths of CVC3, Boolector, and Z3; (3) comprehensive empirical evidence that the approach scales to larger embedded programs and reduces verification time substantially. The authors argue that this methodology opens the door to more widespread adoption of formal verification in safety‑critical embedded development, and it can be combined with automatic code‑generation pipelines, certification processes (e.g., IEC 61508, ISO 26262), and other formal analysis tools.
Comments & Academic Discussion
Loading comments...
Leave a Comment