A topic in the Open Knowledge Graph — a free, open map of 15,290 topics and the order to learn them in.

Symbolic Execution

Research Depth 93 in the knowledge graph ☐ I know this ☆ Set as goal
4topics build on this
430prerequisites beneath it
See this on the map →
Introduction to Propositional LogicProgramming Language Semantics+1 more→→Bounded Model CheckingContract Verification (Blockchain)+2 more
symbolic-execution path-constraint smt concolic klee test-generation

Core Idea

Symbolic execution runs a program with symbolic values (placeholders like alpha, beta) instead of concrete inputs, tracking how these symbols propagate through computations and accumulating path constraints at each branch. When the program branches on a condition involving symbolic values, execution forks: one path adds the condition as a constraint, the other adds its negation. Each path's constraint set characterizes exactly which concrete inputs would follow that path. Feeding path constraints to an SMT solver generates concrete test inputs or proves path infeasibility. Symbolic execution systematically explores all program paths, enabling high-coverage test generation, bug finding, and bounded verification.

Explainer

Testing runs a program on specific concrete inputs and checks the output. This is fast but covers only the tested inputs — bugs on untested paths remain hidden. Symbolic execution inverts this by running the program on symbolic inputs (variables like alpha, beta rather than specific values), tracking how they flow through the computation. When the program computes y = x + 3, the symbolic executor records y = alpha + 3. When it branches on x > 5, it forks into two execution paths: one where alpha > 5 and one where alpha <= 5. Each path accumulates a path constraint — the conjunction of all branch conditions encountered along that path.

At any point, feeding the path constraint to an SMT solver (like Z3) either produces a concrete input satisfying all constraints (a test case that follows that exact path) or proves the constraints unsatisfiable (the path is infeasible — no concrete input can reach it). This gives symbolic execution two superpowers: automatic test generation (produce inputs that exercise specific paths, including hard-to-reach error paths) and bounded verification (if all paths to an error are explored and none is feasible, the error is unreachable within the explored scope).

The central challenge is path explosion: a program with n sequential branches has up to 2n paths. Loops make this worse — a loop with a symbolic bound has a different path for each possible iteration count. Real programs have astronomically many paths, and exhaustive exploration is infeasible. Practical symbolic execution tools use heuristics to prioritize interesting paths (depth-first, coverage-guided, or directed toward specific targets), path merging (combining paths that converge to the same program point, using disjunctive constraints), and bounded analysis (exploring paths up to a fixed depth or loop unrolling bound).

Concolic execution (concrete + symbolic), pioneered by tools like DART and CUTE, addresses another limitation: pure symbolic execution cannot handle operations it cannot model symbolically (system calls, native library functions, complex pointer arithmetic). Concolic execution runs the program concretely with real inputs while simultaneously maintaining symbolic constraints for the operations it can model. It uses the concrete execution to drive progress and the symbolic constraints to generate alternative inputs. By negating one branch condition at a time, it systematically steers the program toward unexplored paths.

Practical impact has been substantial. KLEE (Stanford) found bugs in GNU Coreutils that had survived decades of testing and manual code review. SAGE (Microsoft) uses concolic execution to find security vulnerabilities in Windows applications and file parsers, having found roughly one-third of all security bugs discovered during Windows 7 development. S2E (EPFL) combines symbolic execution with whole-system analysis, testing entire software stacks including OS kernels. angr (UC Santa Barbara) applies symbolic execution to binary analysis, working without source code. The technique has become a standard tool in both security research and software testing, complementing model checking and deductive verification with a path-centric, test-generation-oriented approach.

Practice Questions 3 questions

Prerequisite Chain

Understanding Zero → The Number Zero → Counting to Five → Counting to 10 → Counting to 20 → Counting a Set of Objects Up to 20 → Cardinality: The Last Number Counted → Matching Numerals to Quantities → Subitizing Small Quantities → Addition Within 10 → Number Bonds to 10 → Addition Within 20 → Doubles and Near Doubles → Doubles Facts Within 10 → Near Doubles Facts Within 20 → Mental Math Strategies for Addition → Mental Math: Adding and Subtracting Tens → Addition Within 100 → Repeated Addition as Multiplication → Multiplication as Equal Groups → Multiplication: Arrays → Basic Multiplication Facts (0s, 1s, 2s, 5s, 10s) → Multiplication Facts Within 100 → Division as Equal Sharing → Division as Grouping (Measurement Division) → Division: Grouping (Repeated Subtraction) Model → Division: Fair Sharing Model → Division as Equal Sharing → Division as Grouping → Basic Division Facts → Division Facts Within 100 → Multiplication and Division Fact Families → Relationship Between Multiplication and Division → Division Facts as Inverse of Multiplication → Remainders and Quotients in Division → Division Word Problems → Multi-Step Word Problems → Solving Multi-Step Word Problems → Multiplication Word Problems → Division Word Problems → Introduction to Long Division → Factors and Multiples → Prime and Composite Numbers → Equivalent Fractions → Relating Fractions and Decimals → Decimal Place Value → Integers and the Number Line → Comparing and Ordering Integers → Absolute Value → Adding Integers → Subtracting Integers → Multiplying Integers → Introduction to Exponents → Order of Operations → Integer Order of Operations → Variable Expressions → The Distributive Property → Variables and Expressions Review → Introduction to Polynomials → Adding and Subtracting Polynomials → Multiplying Polynomials → Factorial → Permutations → Combinations → Counting Principles: Addition and Multiplication Rules → Introduction to Graph Theory → Propositional Logic Foundations → Logical Equivalences → Boolean Algebra → Boolean Type and Truth Values → Comparison Operators and Boolean Tests → Logical Operators and Boolean Algebra → Boolean Algebra and Fundamental Laws → Logic Gates Fundamentals → Implementing Boolean Functions with Gates → Karnaugh Map Simplification → Combinational Circuit Design → Flip-Flops and Latches → Finite State Machines (FSMs) → Deterministic Finite Automata (DFA) → Nondeterministic Finite Automata (NFA) → Two-Way Finite Automata → NFA to DFA Conversion (Subset Construction) → DFA Properties and Minimization Algorithms → Regular Languages: Definition and Characterization → Context-Free Grammars (CFGs) → Context-Free Grammar Properties and Ambiguity → Parse Trees, Derivations, and Ambiguity in CFGs → Context-Free Grammars in Compiler Design → Compiler Phases and Organization → Grammar Design for Compilation → Domain-Specific Language Design and Implementation → Programming Language Semantics → Symbolic Execution

Longest path: 94 steps · 430 total prerequisite topics

Prerequisites (3)

Leads To (4)