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.
c9c9171 to
a16528c
Compare
LLGo baseline benchmarks
Program measurements
Core language and compiler benchmarks
Compared only with the latest matching platform in the main series. |
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:
.binbytes to the stripped control.Review follow-ups are included:
Useroutes wasm/wasi through the driver while the directwasm-ldpolicy remains for target-policy callers;Validation on the rebased root (
e82e95fbe) and review-fix head (a16528cf8):GOMAXPROCS=4 GOMEMLIMIT=8GiB GOFLAGS=-p=1 go test -vet=off -count=1 -timeout=5m ./internal/build -run '^(TestDwarfLinkerArgs|TestDwarfPreserveLinkerArgs|TestEffectiveOmitDWARF|TestShouldEmitDebugInfo|TestValidateLinkOptions|TestDwarfLinkerArgsSuppressNativeInputDWARF|TestTargetDWARFDoesNotChangeLoadableELF|TestCollectFingerprint|TestTargetTripleMethod)$'GOMAXPROCS=4 GOMEMLIMIT=8GiB GOFLAGS=-p=1 go test -vet=off -count=1 -timeout=5m ./internal/crosscompileThe complete
internal/buildpackage retains the knownTestRunPrintfWithStdioNobuflong-running test; it is not used as the root validation gate. Dependent PRs will be submitted one layer at a time after this root is reviewed.CI result on a16528c: 41 checks passed, 1 release check skipped by workflow policy, with no failures or cancellations; Codecov reports 100.00% diff coverage (target 89.59%).