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:
-
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.
-
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
- 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.
- Implement the independent LLDB Go language layer and its cross-platform test harness.
- Add LLGo runtime adapters and replace ad hoc Python formatting incrementally.
- Switch LLGo compile units to DW_LANG_Go only after the complete acceptance matrix passes.
- 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.
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:
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:
LLDB Go language layer
LLGo debugger layer
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
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:
Delivery stages
Non-goals