debug: allow supported targets to retain DWARF - #2269
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
Dependency audit: this root PR has no cpunion predecessor. xgo-dev/main already contains the relevant baseline PRs #2141 (DWARF foundation), #2211 (LLDB launcher/schema), and #2240 (strings/slices runtime views); none are duplicated here. The next cpunion layer (#112) depends on this PR and will not be submitted upstream until this root layer is accepted. |
There was a problem hiding this comment.
Review summary
This is a clean, well-tested refactor of DWARF debug-info handling. Replacing the boolean AlwaysOmit with a typed DebugInfoCapability + CanRetain() and splitting PreserveLinkFlags/OmitLinkFlags reads clearly, and the change is backed by thorough unit tests plus a new end-to-end Cortex-M ELF test. No correctness regressions found across code-quality, performance, security, and documentation passes.
Confirmed as correct-by-design:
- The
-Svs-Wl,-Ssplit is intentional: theuse()wasm/native path links through the clang driver (-Wl,-S), whiletargetDebugInfoPolicy(viaUseTarget, directld.lld/wasm-ld) uses bare-S. - Removing the unconditional
-SfromUseTargetldflags is safe: omission still flows throughOmitDWARFByDefault→dwarfLinkerArgs→["-S"]for retainable targets, covered by thefixed target wtest. - No security concerns: flags are hardcoded constants appended as argv elements (no shell/injection surface); test
exec.Commandcalls use fixed tool names guarded byLookPath.
The findings below are all low-severity maintainability/documentation notes, left inline.
| return policy | ||
| } | ||
|
|
||
| func targetDebugInfoPolicy(linker, llvmTarget string) DebugInfoPolicy { |
There was a problem hiding this comment.
targetDebugInfoPolicy is only reached via UseTarget, and Use() routes every wasm/wasi target name to use() instead (crosscompile.go:753). All four wasm-ld target JSONs (wasm, wasm-unknown, wasip1, wasip2) start with those prefixes, so the wasm-ld branch here is never exercised by a real build — only by TestTargetDebugInfoPolicy. Not a bug, but worth a one-line comment noting that wasm/wasi are handled by use() and that this branch is currently test-only.
Separately, any unrecognized (linker, llvmTarget) combination silently falls through to DebugInfoUnavailable, which disables DWARF entirely for that target (via !CanRetain() in shouldEmitDebugInfo). Documenting that intentional fail-to-omit default would help the next person adding a target with a different linker.
| return | ||
| } | ||
| export.DebugInfo.OmitLinkFlags = []string{"-Wl,-S"} | ||
| export.DebugInfo = DebugInfoPolicy{ |
There was a problem hiding this comment.
This wasm policy literal (PreserveLinkFlags: ["-gdwarf-4"], OmitLinkFlags: ["-Wl,-S"]) is identical to what nativeDebugInfoPolicy produces for darwin/linux. Both represent "link through the clang driver", so consider factoring a shared helper (e.g. driverDebugInfoPolicy()) so the -gdwarf-4 / -Wl,-S pairing lives in one place.
Note this also diverges from the wasm-ld branch in targetDebugInfoPolicy (line 88-90), which uses PreserveLinkFlags: nil / OmitLinkFlags: ["-S"] for the same wasm family — a second reason the flag choice tracks "clang driver vs direct linker invocation", not "linker type".
| } | ||
|
|
||
| // dwarfPreserveLinkerArgs returns compiler-driver options needed while linking | ||
| // a debug artifact. Direct linkers such as ld.lld retain input DWARF without a |
There was a problem hiding this comment.
The dichotomy here ("direct linkers such as ld.lld ... without a corresponding flag, while clang-compatible drivers accept -gdwarf-4") is slightly oversimplified: the wasm cross-compile path in crosscompile.go:365-368 assigns -gdwarf-4 even though it links with wasm-ld (a direct linker), because linking there goes through the clang driver. The real determinant is whether the invocation goes through the clang driver, not the linker type. Minor wording tweak would make the comment match all paths.
Part of #2164.
This is the dependency-tree root change. It keeps target debug-artifact policy explicit without pulling any dependent debugger frontend or runtime changes:
Validation on the rebased root:
The complete internal/build package has a pre-existing TestRunPrintfWithStdioNobuf hang; it was not used as a root validation gate. Dependent PRs will be submitted one layer at a time after this root is reviewed.