Open-Source Wikis

/

Zig

/

How to contribute

/

Debugging

ziglang/zig

Debugging

Tools that help when the compiler itself misbehaves.

Crash reports

src/crash_report.zig registers a custom panic handler. When the self-hosted compiler crashes, you get a Zig stack trace plus the source location of the unanalyzed declaration that triggered the failure (when available). src/main.zig wires it up:

pub const panic = crash_report.panic;
pub const debug = crash_report.debug;

If you are debugging a comptime infinite loop or a Sema panic, this is what dumps the cycle.

Pretty-printers

The tools/ directory has GDB and LLDB pretty-printers for the compiler's internal types and the standard library:

File What it prints
tools/lldb_pretty_printers.py (~58 KB) LLDB summaries for Sema, AIR, ZIR, InternPool, Type, Value, etc.
tools/stage1_gdb_pretty_printers.py Stage1-era types (still useful when debugging the bootstrap path).
tools/stage2_gdb_pretty_printers.py Stage2 compiler types.
tools/zig_gdb_pretty_printers.py Generic Zig builtins (slices, optionals, errors).
tools/std_gdb_pretty_printers.py std.ArrayList, std.HashMap, std.Target, etc.

Source them from your .gdbinit/.lldbinit.

Verbose flags

zig build-exe ... -fverbose-{ir,llvm-ir,c,...} dumps the IR at each pipeline stage. The exact set of flags is in src/main.zig's argument parser. Useful pairs:

  • -femit-asm=... and the LLVM-side -fllvm-ir.
  • -femit-zir/-femit-air (when enabled by build options).
  • -fno-llvm to force the self-hosted backend, or -fllvm to force LLVM.

Tracy

src/tracy.zig integrates Tracy zones around the major pipeline stages. Pass -Dtracy=<path> (when the option is exposed by your build configuration) to link Tracy and emit a profile.

Logging the build itself

zig build --verbose, --verbose-cc, --verbose-link, and --verbose-llvm-ir (where supported) make the build runner print exactly what commands it would invoke. The build runner lives in lib/compiler/build_runner.zig.

Incremental compilation debugging

When something only fails under --watch:

  1. Reproduce with tools/incr-check.zig — the harness exposes the same edit/recompile loop deterministically.
  2. Inspect what the watcher told the compiler to invalidate. lib/std/Build/Watch.zig and src/IncrementalDebugServer.zig are the relevant files.
  3. The Zcu keeps a dependency graph; see src/Zcu.zig for the data structures used to invalidate decls.

Reducing a crash

zig reduce (lib/compiler/reduce.zig) is the in-tree minimizer. Given a Zig file and a script that classifies a build as "still buggy" vs "no longer buggy", it produces the smallest reproducer.

Common stumbling blocks

  • OOM during analysis. Sema can build a deep dependency chain; check that you aren't accidentally creating an unbounded comptime recursion.
  • LLVM mismatch. The CMake build pins a specific LLVM version (see CMakeLists.txt's find_package(LLVM ...) lines). Build errors that mention symbol mismatches in src/zig_llvm*.cpp usually mean an LLVM version skew.
  • Stale cache. zig build is cache-aggressive. rm -rf zig-out zig-cache .zig-cache resolves most "I changed something but it didn't take effect" reports.

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

Debugging – Zig wiki | Factory