debug: preserve O0 variable locations - #2235
Conversation
There was a problem hiding this comment.
Review: preserve O0 variable locations
The core mechanism is sound. At O0, diParam allocates a stable entry-block "home" and emits llvm.dbg.declare against it; later DebugRefs refresh that home via a location-less DIStore, so the debugger reads a live value from a fixed slot. The location save/clear/restore in withoutDebugLocation, entry-block dominance of the home alloca, the nil-map guards, and the debugAllocObjects/debugStableParams double-handling exclusion all check out. No blocking issues; findings below are minor/robustness.
Minor
-
ssa/di.go:673— deadLoadindoConstructDebugAddr.doConstructDebugAddralways emitsdbgVal = b.Load(dbgPtr), but its only callers (DIValueatssa/di.go:696and nowdiParamviaconstructDebugAddr) discarddbgValand the hardcodedexists=false. This PR extends the alloca/store/Loadpattern to every parameter home, so an unusedLoadis now emitted per param in O0 IR — pure overhead that isn't cleaned up at O0. Consider dropping theLoad(and the unuseddbgVal/existsreturn values) since no caller uses them. Debug-build only. -
cmd/internal/lldb/llgo_plugin.py— unguarded runtime state / value parsing.print_all_variablesandprint_go_expressionwalktarget → process → thread → frameafter_require_supported_targetwith noframe.IsValid()/process-state check, so invokingllgo vars/llgo printwith a loaded-but-not-launched target yields empty/garbage output instead of a clear "no running process" message. Severalint(x.GetValue(), 16)calls informat_slice/get_indexed_value/format_string, and theparts[i+1]/int(part[1:-1])indexing inevaluate_expression, are unguarded againstNone/non-hex values and malformed tokens, which raise uncaughtTypeError/ValueError/IndexErrorand abort the command. Low severity (interactive input), but worth hardening. -
cmd/internal/lldb/lldb.go— LLDB version regex on Apple toolchains.parseLLDBMajorcaptures the first integer from the--versionstring againstminimumLLDBVersion = 18. On macOS, Apple LLDB reports a build number (e.g.lldb-1700.x), so the check passes only coincidentally rather than validating the underlying LLVM major. Works today; consider special-casing or documenting the Applelldb-<build>format.
Verified as non-issues: the stable.value/block short-circuit and the p.bvals[iv] missing→return path in debugRef match the existing DIValue semantics; debugStableParams is seeded only when DIParamWithHome returns a non-nil home (O0 only); the moved runtest.sh now passes LLDB commands via an argv array instead of eval, closing the earlier injection pattern; comments in internal/debuginfo/builder.go and the lldbtest/README.md are accurate after the move.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
|
Addressed the #2235-specific review finding in Validation after the change:
The runtime-state/value-parsing and Apple version-detection notes concern the parent #2211 launcher/plugin changes, not this compiler-location patch. I am keeping them out of #2235 so this dependent PR stays focused. |
0d38ab3 to
919cea3
Compare
LLGo baseline benchmarks
Program measurements
Core language and compiler benchmarks
No main baseline exists yet; all metrics are marked Warning
|
Fixes #2206.
Problem
With
-O0 -ldflags=-w=falseon Linux/amd64, LLDB could list variables but fail to read scalar parameters at the first body breakpoint. An updated local aggregate could also show a stale value even when reading the same object through a pointer showed the new value.Fix
dbg.declare; do not replace them with aggregate value snapshots.dbg.valuepath for optimized builds.Validation
ssafull coverage: 93.0%; all new parameter-home helpers are covered 100%.clfull coverage: 97.4%; focused final O0/O2 metadata tests pass on both platforms.