Open-Source Wikis

/

LLVM

/

How to contribute

/

Debugging

llvm/llvm-project

Debugging

A practical playbook for tracking down problems in this codebase.

Build with assertions

For development, configure with:

-DCMAKE_BUILD_TYPE=RelWithDebInfo
-DLLVM_ENABLE_ASSERTIONS=ON

LLVM's internal invariants are enforced by assert() and by ad hoc report_fatal_error() calls. A release build with assertions disabled will silently misoptimize where an asserts build would fire a clear failure.

For deep debugging:

-DCMAKE_BUILD_TYPE=Debug
-DLLVM_ENABLE_ASSERTIONS=ON
-DLLVM_USE_LINKER=lld
-DLLVM_PARALLEL_LINK_JOBS=1   # Debug binaries are huge; cap link parallelism

Reduce the input

Most LLVM bug reports start with a giant test case. The first move is almost always to reduce it:

  • llvm-reduce (llvm/tools/llvm-reduce/) — bisects over LLVM IR / MIR to find a minimal failing input.
  • bugpoint (llvm/tools/bugpoint/) — the older but still-useful "automatic test-case reducer". Specializes in pass-pipeline bisection.
  • creduce / cvise — third-party C-source reducers for Clang front-end bugs.

A typical reducer invocation:

llvm-reduce --test=./check.sh input.ll

where check.sh exits 0 on "still reproduces the bug" and non-zero otherwise.

Bisecting passes and changes

Two kinds of bisects come up:

  • Bisect over commits to find the change that broke something:

    git bisect start HEAD <known-good-sha>
    git bisect run ./test.sh

    With a fast incremental build and ccache, a bisect over hundreds of commits is a coffee break.

  • Bisect over passes to find which pass miscompiled IR:

    opt -opt-bisect-limit=N input.ll -o /dev/null

    The -opt-bisect-limit flag (in llvm/lib/IR/OptBisect.cpp) numbers each pass instance. Binary search by N to find the culprit. Once located, dump IR before and after with --print-after=<pass>.

Inspecting IR through the pipeline

# Show IR after every IR pass
opt -O2 -print-after-all input.ll

# Just one pass
opt -O2 -print-after=instcombine input.ll

# Codegen levels
llc input.ll --print-after-all
llc input.ll --print-machineinstrs=mir --debug-only=isel

--debug-only=<flag> selects categories of LLVM_DEBUG() output declared in source. The complete list of flags is whatever any source file calls DEBUG_TYPE with — there is no master registry. Search for DEBUG_TYPE in the area you care about.

Sanitizers (and the compiler-rt runtimes that back them)

A debug build of LLVM should be run under sanitizers when you suspect memory or thread bugs in the compiler itself:

-DLLVM_USE_SANITIZER=Address           # ASan
-DLLVM_USE_SANITIZER=Thread            # TSan
-DLLVM_USE_SANITIZER=Memory            # MSan (needs an instrumented libc++)
-DLLVM_USE_SANITIZER=Undefined         # UBSan

Sanitizer runtimes live in compiler-rt/lib/asan/, compiler-rt/lib/tsan/, compiler-rt/lib/msan/, compiler-rt/lib/ubsan/.

Common failure modes

Symptom First thing to check
Assertion failed: ... Read the assertion message — the file:line and condition usually tell you exactly what invariant was broken.
LLVM ERROR: followed by a message A report_fatal_error(). Backtrace into the calling pass.
Test fails only on one platform Probably a target-specific lowering. Reproduce with -mtriple= set explicitly.
Codegen difference in update_llc_test_checks.py A scheduling change. Compare --print-after-all between good and bad builds.
Crash inside delete this or Use::set Dangling reference in IR — Verifier should catch it. Run opt -verify.
Build error after rebase Usually a TableGen incremental-build glitch. rm -rf build and rebuild.
Linker OOM in debug build Switch to lld and reduce LLVM_PARALLEL_LINK_JOBS.

Debug-info pipelines (LLDB, DWARF, PDB)

Bugs in debug-info correctness often only surface when you run a debugger against the produced binary. Useful tools:

LLDB-specific debugging tips live in lldb/docs/.

When in doubt

  • Search Discourse — most "first time hitting this" issues have been hit before.
  • Check the per-area Maintainers.md (e.g., llvm/Maintainers.md) and CC the maintainer on the GitHub issue or PR.
  • For hard reproducer-required bugs, file a GitHub issue with the reduced IR and a self-contained RUN: line.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Debugging – LLVM wiki | Factory