In this paper, we introduce an interactive simulator for programs in the form of LLVM bitcode. The main features of the simulator include precise control over thread scheduling, automatic checkpoints and reverse stepping, support for source-level information about functions and variables in C and C++ programs and structured heap visualisation. Additionally, DivSIM is compatible with DiVM (DIVINE VM) hypercalls, which makes it possible to load, simulate and analyse counterexamples from an existing model checker, and with abstract bitcode generated by LART (LLVM Abstraction and Refinement Tool), making it suitable for direct analysis of abstract and/or symbolic programs and counterexamples.
This is a preview of subscription content, access via your institution.
Buy single article
Instant access to the full article PDF.
Price excludes VAT (USA)
Tax calculation will be finalised during checkout.
Yes, under an open-source licence.
How this is achieved is described in more detail in .
A minor technical complication arises from the fact that the formatting function needs to be invoked in the context in which the abstract value exists. However, since debug nodes already carry a reference to the snapshot (program state) which they describe and DiVM can cheaply continue execution from an arbitrary snapshot, this is not a serious problem.
There are actually two implementation choices. The evaluation could be handed off to the term domain itself, the same as for formatting abstract values, though in this case it is more complicated, since the model needs to be passed to the evaluation routine. However, since the model checker needs to be able to evaluate the terms anyway to build the SMT query, it seems reasonable to do the evaluation on the DiVM /DivSIM side.
The behaviour of the program may depend on external factors, such as scheduling choices, user inputs, asynchronous events and so on. In DiVM , these all map to the choose hypercall.
This is often the case in verification-centric tools, partly because it is a simple implementation strategy that builds on the same primitives as the verification tool itself.
This description is necessarily incomplete, being much more concise than the real representation of the program’s state. Including additional information improves completeness, but compromises brevity, which is an important strength of this presentation format.
The typical cause will be an out-of-bound memory access on a stack-allocated variable. In real execution, this is not in itself an error, but will be detected and reported by DiVM , since each local variable is allocated in its own memory object (as discussed in Sect. 3).
The source code of the graphical user interface is available from supplementary materials page at https://divine.fi.muni.cz/2021/sim/.
We speculate that this is the primary reason why interactive simulators (and debuggers in general) are so scarce.
At the time of this writing, work is in progress to provide simple Python bindings for the C++ API, via Boost.Python. We believe the Python API will make DivSIM more accessible to 3rd-party developers.
Supported by anecdotal evidence from working with students, both individually and in a validation & verification course.
Abdulla, P.A., Aronis, S., Atig, M.F., Jonsson, B., Leonardsson, C., Sagonas, K.: Stateless model checking for TSO and PSO. Acta Inform. 54(8), 789–818 (2017). https://doi.org/10.1007/s00236-016-0275-0
Ball, T., Naik, M., Rajamani, S.K.: From symptom to cause: localizing errors in counterexample traces. In: POPL, pp. 97–105. ACM (2003)
Ball, T., Cook, B., Levin, V., Rajamani, S.K.: SLAM and static driver verifier: technology transfer of formal methods inside microsoft. In: IFM, LNCS. Springer (2004)
Barnat, J., Beran, J., Brim, L., Kratochvíla, T., Ročkai, P.: Tool chain to support automated formal verification of avionics Simulink designs. In: FMICS, number 7437 in LNCS, pp. 78–92. Springer (2012)
Basu, S., Saha, D., Smolka, S.A.: Getting to the root of the problem: focus statements for the analysis of counter-examples (2012)
Behrmann, G., David, A., Larsen, K.G.: A tutorial on uppaal. In: SFM (2004)
Cadar, C., Dunbar, D., Engler, D.R.: KLEE: Unassisted and automatic generation of high-coverage tests for complex systems programs. In: OSDI, pp. 209–224. USENIX Association (2008)
Chalupa, M., Jašek, T., Tomovič, L., Hruška, M., Šoková, V., Ayaziová, P., Strejček, J., Vojnar, T.: Symbiotic 7: Integration of predator and more. In: TACAS, pp. 413–417. Springer, Cham (2020). ISBN 978-3-030-45237-7
Groce, A., Kroening, D., Lerda, F.: Understanding counterexamples with explain. In: Computer Aided Verification, LNCS, pp. 453–456. Springer (2004)
Günther, H., Laarman, A., Weissenbacher, G.: Vienna Verification Tool: IC3 for parallel software (competition contribution). In: TACAS, pp. 954–957 (2016). https://doi.org/10.1007/978-3-662-49674-9_69
Kleiman, R., Brayshaw, M., Eisenstadt, M., Eisenstadt, M.: Tales of debugging from the front lines (1993)
Kokologiannakis, M., Raad, A., Vafeiadis, V.: Model checking for weakly consistent libraries. In PLDI, PLDI, pp. 96–10, New York, 2019. ACM (2019). https://doi.org/10.1145/3314221.3314609
Lauko, H., Ročkai, P., Barnat, J.: Symbolic computation via program transformation. In: Theoretical Aspects of Computing—ICTAC, pp. 313–332. Springer, Cham (2018)
Lauko, H., Štill, V., Ročkai, P., Barnat, J.: Extending DIVINE with symbolic verification using SMT. In: TACAS, pp. 204–208. Springer, Cham (2019)
Lee, K.: Using LLDB, pp. 415–434. Apress, Berkeley, CA (2013). ISBN 978-1-4302-5051-7
Legay, A., Nowotka, D., Poulsen, D.B., Tranouez, L.-M.: Statistical model checking of llvm code. In: Formal Methods, pp. 542–549. Springer, Cham (2018)
Magee, J.: Behavioral analysis of software architectures using LTSA. In: ICSE (1999)
Nethercote, N., Seward, J.: Valgrind: a framework for heavyweight dynamic binary instrumentation. In: PLDI (2007)
Ročkai, P., Barnat, J.: A simulator for llvm bitcode. In: Formal Methods for Industrial Critical Systems, pp. 127–142. Springer, Cham (2019)
Ročkai, P., Štill, V., Černá, I., Barnat, J.: DiVM: model checking with LLVM and graph memory. J. Syst. Softw. 143, 1–13 (2018). https://doi.org/10.1016/j.jss.2018.04.026
Ročkai, P., Baranová, Z., Mrázek, J., Kejstová, K., Barnat, J.: Reproducible execution of POSIX programs with DiOS. Software and Systems Modeling, pp. 1–20, 10 (2020). https://doi.org/10.1007/s10270-020-00837-y
Stallman, R., Pesch, R., Shebs, S.: Debugging with gdb (2010)
The LLVM Project. LLVM language reference manual (2016). http://llvm.org/docs/LangRef.html
Visan, A.-M., Arya, K.: Gene Cooperman, and Tyler Denniston. URDB: a universal reversible debugger based on decomposing debugging histories. In: PLOS ’11 (2011)
Visser, W., Groce, A.: What went wrong: Explaining counterexamples. In: SPIN, LNCS, pp. 121–135. Springer (2002)
Conflict of interest
The authors declare that they have no conflict of interest.
Springer Nature remains neutral with regard to jurisdictional claims in published maps and institutional affiliations.
The present paper is an extended version of .
Rights and permissions
About this article
Cite this article
Ročkai, P., Barnat, J. DivSIM , an interactive simulator for LLVM bitcode. Int J Softw Tools Technol Transfer 24, 493–510 (2022). https://doi.org/10.1007/s10009-022-00659-x
- Model checking
- Abstract interpretation
- Symbolic execution