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=ONLLVM'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 parallelismReduce 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.llwhere 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.shWith 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/nullThe
-opt-bisect-limitflag (inllvm/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 # UBSanSanitizer 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:
llvm-dwarfdump(llvm/tools/llvm-dwarfdump/) — pretty-print DWARF.llvm-objdump --dwarf=...— dump DWARF inline with disassembly.llvm-pdbutil(llvm/tools/llvm-pdbutil/) — inspect PDB.
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.