Open-Source Wikis

/

Swift

/

How to contribute

/

Debugging

apple/swift

Debugging

Tips for debugging the Swift compiler, the Swift runtime, and Swift programs themselves. The canonical reference is docs/DebuggingTheCompiler.md.

Debugging the frontend

Useful flags

Flag Effect
-print-ast Pretty-print the typed AST.
-emit-sil, -emit-silgen Print canonical / raw SIL.
-emit-ir Print LLVM IR.
-Xfrontend -dump-ast Dump the raw AST after sema.
-Xllvm -sil-print-pass-name Print the SIL after each pass.
-Xllvm -sil-print-function=foo Print SIL for a single function across passes.
-Xllvm -sil-print-types Include types in printed SIL.
-debug-constraints (Sema) Verbose dump of the constraint solver.
-debug-time-function-bodies Per-function time spent type-checking.
-stats-output-dir <dir> Write frontend-stats.json for compiler-performance analysis.

Running under a debugger

lldb -- ./bin/swift-frontend -typecheck path/to/repro.swift
(lldb) breakpoint set -n swift::TypeChecker::checkDeclaration
(lldb) run

The Swift project ships a few LLDB helpers for compiler types in utils/lldb/:

  • utils/lldb/lldbToolBox.py -- pretty printers for Type, Decl, SILValue.

Source it in your ~/.lldbinit:

command script import /path/to/swift/utils/lldb/lldbToolBox.py

SIL passes

The optimizer pipeline is registered in lib/SILOptimizer/PassManager/. To debug a single pass:

  • -Xllvm -debug-only=<pass-name> -- per-pass debug output (LLVM -debug-only).
  • -Xllvm -sil-print-after=<pass-name> -- dump SIL after a specific pass.
  • -Xllvm -sil-disable-pass=<pass-name> -- disable a pass to bisect.

For Swift-implemented passes (in SwiftCompilerSources/Sources/Optimizer/), the pass name is the Swift type name (AllocBoxToStack, DestroyHoisting, ...).

Debugging Swift programs

Runtime debug environment

The Swift runtime reads many environment variables, all listed in stdlib/public/runtime/EnvironmentVariables.def:

Variable Effect
SWIFT_DEBUG_RUNTIME_ENVIRONMENT_VARIABLES=1 Print the recognized variables on startup.
SWIFT_DEBUG_FAILED_TYPE_LOOKUP=1 Trace dynamic type lookup failures.
SWIFT_BACKTRACE=enable=yes Enable the backtracer (docs/Backtracing.rst).
SWIFT_DETERMINISTIC_HASHING=1 Use a fixed hash seed (useful for reproducing bugs).
SWIFT_DEBUG_ENABLE_MALLOC_SCRIBBLE=1 Force-poison metadata allocations.

Backtracing

Swift ships its own user-space backtracer (stdlib/public/RuntimeModule/) plus a self-test harness in utils/backtrace-check. Invoke crashes with SWIFT_BACKTRACE=enable=yes,sanitize=preset to see the symbolicated trace. See docs/Backtracing.rst.

Crash recovery

The runtime registers crash handlers (stdlib/public/runtime/CrashHandler*.cpp) per-platform: CrashHandlerLinux.cpp, CrashHandlerMacOS.cpp, CrashHandlerWindows.cpp. They produce swift-runtime-crash.log-style output.

Debugging stdlib correctness

StdlibUnittest (stdlib/private/StdlibUnittest/) supports expectCrashLater() for tests that intentionally trap. To diagnose:

  • Run a single test executable directly: ./build/.../bin/swift-test-....
  • Pass --filter to limit to one test.
  • Set SWIFT_DETERMINISTIC_HASHING=1 to reproduce hash-table flakes.

Common reproducer reductions

For compiler crashes, utils/bug_reducer/ automates SIL- and source-level reduction:

  • bug_reducer.py -- top-level reducer.
  • swift_tools.py -- wrappers around the toolchain.
  • sil-passpipeline-dumper.py -- dump the pass pipeline that triggered the bug.

For C++/Clang interop issues, the lib/ClangImporter/ Swift snapshot uses LLVM's c-index-test patterns; reduce the C++ header with creduce or cvise.

Where to read more

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

Debugging – Swift wiki | Factory