Symbolic Execution Engine

Find every
bug. Explore
every path.

KLEE is a dynamic symbolic execution engine built on LLVM. It automatically generates tests with high coverage and finds deep bugs that manual testing misses entirely.

klee — symbolic analysis session
What is KLEE

Symbolic execution,
made accessible

KLEE is a dynamic symbolic execution engine built on LLVM, available under the UIUC open source license. Instead of running a program with one specific input, KLEE treats inputs as symbolic variables that can hold any value.

By doing this, KLEE simultaneously explores all feasible execution paths through a program. At each branch, it asks a constraint solver: "can this branch be taken?" — and forks the execution state for every feasible answer. When it finds a crash or violation, it hands you the exact concrete input that triggers it.

The original OSDI 2008 paper ran KLEE on 89 GNU Coreutils programs and found 56 bugs — including ones that had existed for years. It is now cited in thousands of research papers and used to analyze operating systems, cryptographic libraries, and firmware.

C — annotating inputs
// 1. Include KLEE header
#include <klee/klee.h>

int main() {
  char buf[8];
  // 2. Mark memory as symbolic
  klee_make_symbolic(buf, sizeof(buf), "input");

  // KLEE explores ALL possible values of buf
  if (buf[0] == 'K' && buf[1] == 'L') {
    if (buf[2] == 'E' && buf[3] == 'E') {
      klee_assert(0); // KLEE finds this!
    }
  }
  return 0;
}
01

Symbolic VM Engine

Executes LLVM bitcode with symbolic values. Handles path forking, constraint collection, and error detection. Lives in lib/.

02

POSIX Emulation Layer

Makes files, pipes, env vars, and CLI arguments symbolic — enabling analysis of programs that interact with the OS.

03

SMT Constraint Solver

Interfaces with STP, Z3, and MetaSMT to determine which branches are feasible and generate concrete triggering inputs.

04

Native Replay Library

Replays computed test inputs on native code with the exact environment state — files, pipes, arguments — that KLEE computed.

Getting Started

Everything you need,
right here

Choose your installation method below. All documentation is embedded — no external links needed.

Docker
★ Recommended
Package Manager
Linux / macOS / BSD
Nix
Fastest after Docker
Homebrew
macOS / Linux
Build from Source
Full control
Platform:

Using KLEE with Docker

Docker provides a fully pre-built KLEE environment that works identically on Linux, macOS, and Windows. This is the fastest and most reliable way to get started — no build steps, no dependency management.

01

Install Docker

If you don't already have Docker, install it for your OS. Docker provides containerised environments that are isolated from your system.

Linux

Use the official Docker apt repository for the latest stable version.
Install guide →

macOS

Download Docker Desktop — includes Docker Engine, CLI, and Compose.
Download Docker Desktop →

Windows

Docker Desktop for Windows with WSL2 backend recommended.
Install guide →

Verify Install

Once installed, confirm Docker is working with this command.
docker --version
02

Pull the KLEE Image

Pull the official KLEE Docker image from DockerHub. The image is based on Ubuntu 22.04 LTS and includes KLEE, LLVM 13, Clang, and Z3/STP solvers pre-installed.

shell — pull latest
docker pull klee/klee

Or pull a specific tagged release:

shell — tagged release
docker pull klee/klee:3.2    # latest stable
docker pull klee/klee:3.0
docker pull klee/klee:2.3
Note: This pulls images compiled by a third-party CI service. The KLEE team does not accept responsibility for image contents. For production use, build the image locally (see below).
03

Quick Start — Verify It Works

Run a temporary container and get a shell. The --rm flag destroys the container when you exit. The --ulimit flag sets unlimited stack size to prevent stack overflow issues inside KLEE.

shell
docker run --rm -ti --ulimit='stack=-1:-1' klee/klee:3.2

If successful, your prompt changes to the klee user inside the container. Verify KLEE and Clang are available:

inside container
klee@container:~$ klee --version
KLEE 3.2 (https://klee-se.org)
  Build mode: RelWithDebInfo (Asserts: TRUE)
  LLVM version 13.0.1

klee@container:~$ clang --version
clang version 13.0.1
Target: x86_64-unknown-linux-gnu

Exit the temporary container:

inside container
klee@container:~$ exit
04

Run Your First KLEE Analysis

Create a persistent named container, write a simple C program, compile to LLVM bitcode, and run KLEE on it.

shell — create persistent container
docker run -ti --name=my_klee --ulimit='stack=-1:-1' klee/klee

Inside the container, create a simple test program:

inside container — create test.c
klee@container:~$ cat > test.c << 'EOF'
#include <klee/klee.h>
#include <assert.h>

int main() {
  int x, y;
  klee_make_symbolic(&x, sizeof(x), "x");
  klee_make_symbolic(&y, sizeof(y), "y");

  if (x + y > 1000) {
    if (x > y) {
      klee_assert(0); /* KLEE will find this */
    }
  }
  return 0;
}
EOF
inside container — compile & run
klee@container:~$ clang -emit-llvm -g -c -O0 test.c -o test.bc
klee@container:~$ klee test.bc

KLEE: output directory is "klee-out-0"
KLEE: Using STP solver backend

KLEE: done: total instructions = 37
KLEE: done: completed paths    = 3
KLEE: done: generated tests    = 3

KLEE: ERROR: test.c:11: ASSERTION FAIL: 0
KLEE: NOTE: now ignoring this error at this location
Success! KLEE found the failing assertion. The output directory klee-out-0/ contains .ktest files — one per path — including one that reproduces the assertion failure with concrete values of x and y.
05

Inspect Results & Replay

KLEE outputs a klee-out-N/ directory with one .ktest file per explored path. Use ktest-tool to inspect the concrete values, or use klee-replay to re-run your native binary with those exact inputs.

inside container
klee@container:~$ ls klee-last/
assembly.ll  info  messages.txt  run.istats  run.stats
test000001.ktest  test000002.ktest  test000003.assert.err  test000003.ktest

klee@container:~$ ktest-tool klee-last/test000003.ktest
ktest file : 'klee-last/test000003.ktest'
args       : ['test.bc']
num objects: 2
object  0: name: 'x'  size: 4  value: 1001
object  1: name: 'y'  size: 4  value: 0

The values x=1001, y=0 satisfy both conditions and trigger the assertion. KLEE generated this without you providing any inputs.

06

Persistent Containers & File Mounting

Stop and restart a named container — your files persist. Mount your host filesystem using --volume to analyse your own code.

shell — stop and restart
# Exit the container (files persist)
klee@container:~$ exit

# See container still exists
docker ps -a

# Restart it
docker start -ai my_klee

# When done, remove it
docker rm my_klee
shell — mount your code
docker run -ti --rm --ulimit='stack=-1:-1' \
  --volume=$(pwd):/home/klee/mycode \
  klee/klee
Tips: The klee user has sudo access (password: klee) so you can install editors or tools. The image is based on Ubuntu 22.04 LTS. Do not use this image in production — the default user has sudo.
07

Build the Image Locally (Optional)

If you prefer to build the Docker image yourself rather than pulling from DockerHub:

shell
git clone https://github.com/klee/klee.git
cd klee
docker build -t klee/klee .

This builds from the Dockerfile in the root of the repository and takes 15–30 minutes depending on your machine.

OS:

Package Manager Installation

Install KLEE directly from your distribution's package repositories. Quick and easy — no manual compilation. Package versions may trail the latest release slightly.

01

Snap Store (Ubuntu / Fedora / Debian)

The Snap package works on Ubuntu, Fedora, Debian, and other major Linux distributions that support Snap.

shell
sudo snap install klee
View on Snap Store →
02

Verify Installation

shell
klee --version
03

Run KLEE on Your Code

shell
# Compile to LLVM bitcode with debug info
clang -emit-llvm -g -c -O0 yourfile.c -o yourfile.bc

# Run KLEE
klee yourfile.bc
01

Arch Linux (AUR / pacman)

KLEE is available in the Arch User Repository.

shell — using yay
yay -S klee
shell — manual AUR
git clone https://aur.archlinux.org/klee.git
cd klee
makepkg -si
Check package versions across distros →
01

FreeBSD

Install the latest KLEE release via pkg or build from the ports tree.

shell — via pkg
pkg install klee
shell — from ports
cd /usr/ports/security/klee
make install clean
FreshPorts listing →
01

openSUSE Tumbleweed

shell
zypper install klee

Running KLEE with Nix

Nix is even faster than Docker if you already have it installed. Nix handles all dependencies declaratively and reproducibly without modifying your system.

01

Install Nix

If you don't have Nix installed yet, the official installer handles everything:

shell
curl -L https://nixos.org/nix/install | sh
02

Run KLEE Without Installing

Use nix run to try KLEE instantly without permanently installing anything:

shell
nix run nixpkgs#klee
03

Enter a KLEE Shell Environment

shell
nix shell nixpkgs#klee nixpkgs#clang

Your shell now has klee and clang available. Compile to bitcode and run KLEE as usual.

04

Declarative Nix Flake

For reproducible project environments, add KLEE to a flake.nix:

nix — flake.nix
{
  inputs.nixpkgs.url = "github:NixOS/nixpkgs";
  outputs = { nixpkgs, ... }: {
    devShells.x86_64-linux.default =
      nixpkgs.legacyPackages.x86_64-linux.mkShell {
        packages = with nixpkgs.legacyPackages.x86_64-linux; [
          klee clang z3 llvm
        ];
      };
  };
}
shell — enter the dev shell
nix develop

Install via Homebrew

Homebrew works on both macOS and Linux. This installs the latest KLEE release with a single command.

01

Install KLEE

shell
brew install klee

Homebrew handles all dependencies (LLVM, Z3, etc.) automatically.

02

Verify

shell
klee --version
which klee  # should show brew path
03

Compile & Run

shell
# Use the Clang from LLVM (not Apple Clang)
$(brew --prefix llvm)/bin/clang \
  -emit-llvm -g -c -O0 test.c -o test.bc

klee test.bc
macOS note: Use LLVM's clang (from the brew formula), not Apple's built-in Clang. Apple Clang does not support -emit-llvm for producing KLEE-compatible bitcode.
Target:

Build from Source

Full control over the build configuration. Recommended for researchers and contributors who need custom KLEE configurations, specific solver combinations, or want to modify KLEE itself.

01

Install Dependencies

KLEE requires LLVM 16, a C++ compiler, CMake, and at least one SMT solver.

shell — Ubuntu 22.04
sudo apt update
sudo apt install -y \
  build-essential cmake git python3 \
  llvm-16 llvm-16-dev clang-16 \
  libz3-dev zlib1g-dev libssl-dev
02

Install STP Solver (Optional)

STP is KLEE's default solver and often faster for certain workloads. Z3 is also supported.

shell
git clone https://github.com/stp/stp.git
mkdir stp/build && cd stp/build
cmake -DBUILD_SHARED_LIBS:BOOL=OFF \
      -DENABLE_PYTHON_INTERFACE:BOOL=OFF ..
make -j$(nproc)
sudo make install
cd ../..
03

Clone & Build KLEE

shell
git clone https://github.com/klee/klee.git
mkdir klee/build && cd klee/build

cmake \
  -DENABLE_SOLVER_STP=ON \
  -DENABLE_SOLVER_Z3=ON \
  -DENABLE_POSIX_RUNTIME=ON \
  -DKLEE_RUNTIME_BUILD_TYPE=Release+Debug+Asserts \
  -DLLVM_CONFIG_BINARY=$(which llvm-config-16) \
  ..

make -j$(nproc)
sudo make install
Tip: Pass -DCMAKE_BUILD_TYPE=Release for a faster binary. Use RelWithDebInfo (default) if you need debug symbols for development.
04

Verify & Test

shell
klee --version
make check # run the test suite
01

Automated Build Script

For building arbitrary KLEE configurations — including different LLVM versions, solver combinations, and optional components — use the automated build script from the repo.

shell
git clone https://github.com/klee/klee.git
cd klee
./scripts/build/build.sh --help

The script supports flags for LLVM version, solver selection, coverage builds, and more. See the build script documentation for all options.

Features

Built for deep
program analysis

Path Exploration

Systematically explores all feasible execution paths using search heuristics like coverage-guided and random-path selection.

Automatic Tests

Generates high-coverage test suites automatically. Each test corresponds to a distinct path, including corner cases humans miss.

Error Detection

Finds memory errors, division by zero, buffer overflows, assertion failures — with a concrete input to reproduce each one.

SMT Solver Integration

Interfaces with STP, Z3, and MetaSMT. Supports query caching, solver chaining, and counterexample-guided optimisation.

POSIX Emulation

Makes file systems, env vars, pipes, and CLI arguments symbolic — for analysing programs that interact with the OS.

LLVM Backbone

Built on LLVM — supports C, C++, Rust, and any language that compiles to LLVM IR. Works with the modern toolchain.

Coverage Reports

Detailed branch, line, and instruction coverage stats. Outputs .ktest files compatible with standard replay tools.

Constraint Caching

Sophisticated caching and independence-based solver optimisations. Avoids re-solving previously seen constraints.

Docker First-class

Official images updated with every release. Pull and analyse in minutes — no build environment setup required.

How It Works

Symbolic path exploration
visualised

KLEE forks execution at every branch, building a tree of all reachable program states. Each node is a constraint set; each leaf is a test case.

PATH EXPLORATION TREE
Completed path Error found Active state Pruned (infeasible)
01

Mark Inputs Symbolic

Use klee_make_symbolic() to declare variables that should hold all possible values.

02

Compile to Bitcode

Compile with Clang using -emit-llvm to produce LLVM bitcode for KLEE to interpret.

03

KLEE Forks at Branches

At each conditional, KLEE asks an SMT solver whether each branch is feasible and forks execution.

04

Collect Test Cases

Every explored path becomes a .ktest file with concrete inputs. Errors include the triggering input.

Impact

Proven at scale

0+
Academic Citations
Papers using KLEE
0
GNU Coreutils Bugs
Found in original paper
0%
Branch Coverage
Achieved on Coreutils
0
Years in Production
Since OSDI 2008
Research

Foundational papers

Community

Join the ecosystem

Get Help

Ask questions, report bugs, and get answers from the KLEE team and community.

Contribute

KLEE is open source under the UIUC license. All contributions welcome.

Events

The International KLEE Workshop brings researchers and practitioners together annually.

Start finding bugs
that matter.

Free, open source, and battle-tested since 2008. Get a shell with KLEE in 60 seconds.

Get Started Now Documentation