Skip to content

proposal: add an LLDB Go language extension for LLGo #2154

Description

@cpunion

Motivation

LLGo can emit structurally valid Go DWARF, but current Apple/LLVM LLDB builds do not provide a Go language plugin. When a compile unit is marked DW_LANG_Go, LLDB warns that frame-variable inspection is limited and hides otherwise valid parameters and locals. The same DIEs are visible when the compile unit is temporarily marked DW_LANG_C.

The existing _lldb/llgo_plugin.py formats Go values and provides simple Go-oriented commands, but it is a Python presentation layer. It cannot make LLDB's core accept DW_LANG_Go, and its current compiler check accepts every target.

Goal

Provide an LLDB language extension that makes LLGo-generated Go programs fully debuggable while preserving standards-compliant Go DWARF.

The extension should eventually allow LLGo to emit DW_LANG_Go without losing frame variables, and should cover Go source types, expressions, stepping, stack frames, and runtime-specific views.

Compatibility transition

Until the native Go language extension is available and tested:

  • LLGo debug compile units use DW_LANG_C so stock LLDB exposes parameters and locals.
  • DW_AT_producer = "LLGo" remains the authoritative compiler identity.
  • LLGo also emits a small, versioned debugger marker that LLDB's public API can query without parsing raw DWARF. Apple LLDB's SBCompileUnit exposes the language but not DW_AT_producer, so producer alone is not sufficient for the Python plugin.
  • _lldb/llgo_plugin.py applies Go formatting only when that marker identifies an LLGo target.
  • Standard DWARF validation still checks the producer, type layouts, scopes, locations, and line tables independently of LLDB.

After the language extension passes the acceptance matrix, switching the compile-unit language from DW_LANG_C to DW_LANG_Go is a separate, explicit change.

Proposed structure

Keep the implementation in two layers:

  1. LLDB Go language layer

    • registers support for DW_LANG_Go;
    • enables normal frame-variable discovery and source-language behavior;
    • maps LLGo DWARF types and declarations into LLDB's type system;
    • owns Go expression semantics that cannot be represented by the C evaluator.
  2. LLGo debugger layer

    • detects the versioned LLGo marker;
    • supplies LLGo runtime layouts and version-specific adapters;
    • provides Go summaries and synthetic children for strings, slices, maps, channels, interfaces, function values, and runtime objects;
    • provides convenience commands and runtime views without replacing LLDB's normal variable model.

The core language support should not depend on LLGo runtime internals. Runtime-version adapters should remain isolated so layout changes do not alter the language plugin.

Execution flow

load executable
    |
    +-- detect DW_LANG_Go
    |       |
    |       +-- LLDB Go language layer enables frame variables,
    |           source behavior, types, and expressions
    |
    +-- detect LLGo marker and version
            |
            +-- install matching LLGo runtime adapter,
                summaries, synthetic children, and commands

During the compatibility period, DW_LANG_C takes the first branch through LLDB's C support, while the LLGo marker still enables the second branch.

Coverage

The extension should be tested with real LLGo binaries, not only mocked SBValue objects:

  • parameters, named results, locals, shadowing, closures, methods, generics, and globals;
  • every primitive type plus aliases and named/recursive types;
  • arrays, strings, slices, maps, channels, interfaces, pointers, structs, and function values;
  • breakpoints, source lines, stepping, stack frames, and variable lifetimes;
  • optimized builds at O0, O1, O2, O3, Os, and Oz, with explicit expectations for optimized-out values;
  • macOS Apple LLDB and Linux LLVM LLDB;
  • marker rejection for non-LLGo C/C++ binaries and a clear response for unsupported marker versions;
  • both linked executables and LLGo-built libraries where LLDB can load their debug information.

Delivery stages

  1. Restore stock-LLDB compatibility with DW_LANG_C, add the versioned LLGo marker, and keep the existing LLDB acceptance suite alongside standards-based DWARF tests.
  2. Implement the independent LLDB Go language layer and its cross-platform test harness.
  3. Add LLGo runtime adapters and replace ad hoc Python formatting incrementally.
  4. Switch LLGo compile units to DW_LANG_Go only after the complete acceptance matrix passes.
  5. Add advanced runtime views such as goroutine-aware stacks as separate follow-up work.

Non-goals

  • Changing Go or DWARF semantics to match limitations in a particular LLDB release.
  • Encoding LLGo runtime implementation details into the generic Go language layer.
  • Treating the Python formatter alone as complete DW_LANG_Go support.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions