Symbolic execution is a popular program analysis technique that allows seeking for bugs by reasoning over multiple alternative execution states at once. As the number of states to explore may grow exponentially, a symbolic executor may quickly run out of space. For instance, a memory access to a symbolic address may potentially reference the entire address space, leading to a combinatorial explosion of the possible resulting execution states. To cope with this issue, state-of-the-art executors either concretize symbolic addresses that span memory intervals larger than some threshold or rely on advanced capabilities of modern satisfiability modulo theories solvers. Unfortunately, concretization may result in missing interesting execution states, for example, where a bug arises, while offloading the entire problem to constraint solvers can lead to very large query times. In this article, we first contribute to systematizing knowledge about memory models for symbolic execution, discussing how four mainstream symbolic executors deal with symbolic addresses. We then introduce MEMSIGHT, a new approach to symbolic memory that reduces the need for concretization: rather than mapping address instances to data as previous approaches do, our technique maps symbolic address expressions to data, maintaining the possible alternative states resulting from the memory referenced by a symbolic address in a compact, implicit form. Experiments on prominent programs show that MEMSIGHT, which we implemented in both ANGR and KLEE, enables the exploration of states that are unreachable for memory models that perform concretization and provides a performance level comparable with memory models relying on advanced solver theories.
MEMORY MODELS IN SYMBOLIC EXECUTION: KEY IDEAS AND NEW THOUGHTS3 of 35 used in the context of state-of-the-art symbolic executors. A crucial design goal for our approach is that it should be general enough not only to support bug detection but also to be valuable in application contexts where users are interested in possible consequences of these bugs, for example, understanding how they can be exploited.Our approach, which we call MEMSIGHT, natively accounts for merging [3,4], a mainstream performance enabler in symbolic executors. We integrated MEMSIGHT into the state-of-the-art symbolic executors ANGR [5] and KLEE [6]: an experimental evaluation shows that MEMSIGHT allows for broader state exploration on prominent benchmarks analysed with ANGR, while it provides valuable run-time speedups when symbolically executing real-world programs under KLEE.A preliminary version [7] of this work appeared in the Proceedings of the 32nd IEEE/ACM International Conference on Automated Software Engineering (ASE 2017), where we introduced the main idea behind MEMSIGHT (Section 3) and presented a preliminary experimental evaluation related to MEMSIGHT when integrated into ANGR (Section 5.2.2). ‡ For our example to be meaningful, we assume that b resides in memory rather than in a CPU register. § In SMT-LIB [9], the theories of...