Skip to content

debug: unify artifacts and native/embedded sessions - #2269

Open
cpunion wants to merge 13 commits into
xgo-dev:mainfrom
cpunion:codex/debug-artifact-policy-2164-20260801
Open

cpunion wants to merge 13 commits into
xgo-dev:mainfrom
cpunion:codex/debug-artifact-policy-2164-20260801

Conversation

@cpunion

@cpunion cpunion commented Aug 3, 2026 •

Copy link
Copy Markdown
Collaborator

Add llgo debug and explicit debug-artifact policies for native, embedded and Wasm builds.

  • Debug sessions preserve DWARF, default to O0, reject stripping flags and launch LLDB or GDB with managed server/process cleanup.
  • Add -debug-artifact=embedded|external|host|none, option validation, sidecar cleanup and separate debug/deployment/runtime-symbol size reporting. Native macOS/Linux/Windows retain platform-toolchain DWARF packaging.
  • Keep embedded DWARF in the host ELF without changing deployment bytes. Support remote GDB servers and OpenOCD, including reset/download/reset with both debuggers. Automatic OpenOCD sessions load the image; existing remote/custom-server sessions load only with -load.
  • Pair external Wasm DWARF with the module through build identity, debugger ABI and external_debug_info, preserving executable sections and Emscripten glue.

Validation: artifact/session regression tests and all PR checks pass. The embedded CI matrix covers Linux/macOS/Windows × GDB/LLDB; QEMU acceptance checks image loading, source breakpoints, variables, backtraces, DWARF validity and unchanged flash bytes.

Physical hardware has not been tested. Native dSYM/debug-file generation is outside this PR's scope.

@codecov

codecov Bot commented Aug 3, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.64220% with 19 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/build/debug_artifact_external.go 87.95% 10 Missing ⚠️
internal/build/build.go 60.00% 4 Missing ⚠️
internal/wasmdebug/wasmdebug.go 98.29% 3 Missing ⚠️
internal/build/artifact_report.go 97.56% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

@cpunion
cpunion marked this pull request as ready for review August 3, 2026 01:24
@cpunion

cpunion commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator Author

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.

@fennoai fennoai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 -S vs -Wl,-S split is intentional: the use() wasm/native path links through the clang driver (-Wl,-S), while targetDebugInfoPolicy (via UseTarget, direct ld.lld/wasm-ld) uses bare -S.
  • Removing the unconditional -S from UseTarget ldflags is safe: omission still flows through OmitDWARFByDefault → dwarfLinkerArgs → ["-S"] for retainable targets, covered by the fixed target w test.
  • No security concerns: flags are hardcoded constants appended as argv elements (no shell/injection surface); test exec.Command calls use fixed tool names guarded by LookPath.

The findings below are all low-severity maintainability/documentation notes, left inline.

Comment thread internal/crosscompile/crosscompile.go
Comment thread internal/crosscompile/crosscompile.go Outdated
Comment thread internal/build/link_options.go Outdated
@cpunion
cpunion marked this pull request as draft August 3, 2026 02:50
@cpunion
cpunion force-pushed the codex/debug-artifact-policy-2164-20260801 branch from c9c9171 to a16528c Compare August 9, 2026 19:21
@github-actions

github-actions Bot commented Aug 9, 2026 •

Copy link
Copy Markdown

LLGo baseline benchmarks

c0263bf07eaf | workflow run | long-term charts

Program measurements

Platform Workload File size vs base Text size vs base Build vs base Run vs base
Linux cprintf 8568 B 0 B / +0.0% 387 B 0 B / +0.0% 1.095 s -25.9 ms / -2.3% (better) 1.396 ms -81.45 us / -5.5% (better)
Linux cprintf-lto 8408 B 0 B / +0.0% 368 B 0 B / +0.0% 1.106 s -63.87 ms / -5.5% (better) 1.355 ms -62.44 us / -4.4% (better)
Linux fmtprintf 4879928 B -8 B / -0.0001639% (better) 501313 B 0 B / +0.0% 8.591 s -752.5 ms / -8.1% (better) 3.366 ms +69.38 us / +2.1% (worse)
Linux fmtprintf-lto 3598288 B 0 B / +0.0% 438157 B 0 B / +0.0% 18.385 s -462.5 ms / -2.5% (better) 3.210 ms +68.06 us / +2.2% (worse)
Linux println 674368 B 0 B / +0.0% 16855 B 0 B / +0.0% 1.128 s -60.4 ms / -5.1% (better) 1.667 ms -86.63 us / -4.9% (better)
Linux println-lto 189992 B 0 B / +0.0% 14273 B 0 B / +0.0% 1.401 s -188 ms / -11.8% (better) 1.738 ms -45.51 us / -2.6% (better)
macOS cprintf 50736 B 0 B / +0.0% 4409 B 0 B / +0.0% 1.690 s +227.2 ms / +15.5% (worse) 8.000 ms +2.569 ms / +47.3% (worse)
macOS cprintf-lto 50496 B 0 B / +0.0% 161 B 0 B / +0.0% 1.301 s -314.8 ms / -19.5% (better) 3.451 ms -2.246 ms / -39.4% (better)
macOS fmtprintf 1773456 B 0 B / +0.0% 877416 B 0 B / +0.0% 7.457 s +280.6 ms / +3.9% (worse) 15.145 ms +149.3 us / +1.0% (worse)
macOS fmtprintf-lto 1360928 B 0 B / +0.0% 761916 B 0 B / +0.0% 14.162 s -2.939 s / -17.2% (better) 6.172 ms -2.939 ms / -32.3% (better)
macOS println 99344 B 0 B / +0.0% 24222 B 0 B / +0.0% 1.279 s -358.6 ms / -21.9% (better) 4.856 ms -27.5 us / -0.6% (better)
macOS println-lto 83664 B 0 B / +0.0% 21457 B 0 B / +0.0% 1.799 s -16.96 ms / -0.9% (better) 5.642 ms +426.3 us / +8.2% (worse)
Windows MinGW cprintf 649728 B 0 B / +0.0% 4550 B 0 B / +0.0% 1.792 s -68.5 ms / -3.7% (better) 4.306 ms +310.3 us / +7.8% (worse)
Windows MinGW cprintf-lto 43520 B 0 B / +0.0% 4486 B 0 B / +0.0% 1.799 s -75.95 ms / -4.0% (better) 3.859 ms -55.5 us / -1.4% (better)
Windows MinGW fmtprintf 5431296 B 0 B / +0.0% 600006 B 0 B / +0.0% 7.632 s -299.3 ms / -3.8% (better) 8.400 ms -2.544 ms / -23.2% (better)
Windows MinGW fmtprintf-lto 4124160 B 0 B / +0.0% 546246 B 0 B / +0.0% 15.619 s -81.2 ms / -0.5% (better) 10.607 ms +1.848 ms / +21.1% (worse)
Windows MinGW println 705536 B 0 B / +0.0% 25190 B 0 B / +0.0% 1.766 s -84.86 ms / -4.6% (better) 7.559 ms +172.7 us / +2.3% (worse)
Windows MinGW println-lto 208896 B 0 B / +0.0% 22054 B 0 B / +0.0% 2.055 s -76.19 ms / -3.6% (better) 6.977 ms -447.9 us / -6.0% (better)
Windows MinGW 386 cprintf 601088 B 0 B / +0.0% 5326 B 0 B / +0.0% 1.849 s +58.96 ms / +3.3% (worse) 6.325 ms +1.11 ms / +21.3% (worse)
Windows MinGW 386 cprintf-lto 103424 B 0 B / +0.0% 5094 B 0 B / +0.0% 1.898 s +39.38 ms / +2.1% (worse) 5.914 ms +722.4 us / +13.9% (worse)
Windows MinGW 386 fmtprintf 4743680 B 0 B / +0.0% 472302 B 0 B / +0.0% 7.985 s -242.7 ms / -2.9% (better) 12.007 ms +1.403 ms / +13.2% (worse)
Windows MinGW 386 fmtprintf-lto 4146176 B 0 B / +0.0% 450818 B 0 B / +0.0% 16.044 s -13.71 ms / -0.1% (better) 13.094 ms -1.37 ms / -9.5% (better)
Windows MinGW 386 println 651776 B 0 B / +0.0% 21490 B 0 B / +0.0% 1.874 s +29.42 ms / +1.6% (worse) 9.944 ms +422.2 us / +4.4% (worse)
Windows MinGW 386 println-lto 258560 B 0 B / +0.0% 19306 B 0 B / +0.0% 2.100 s +69.91 ms / +3.4% (worse) 9.099 ms -207.4 us / -2.2% (better)
Windows MinGW ARM64 cprintf 660480 B 0 B / +0.0% 4408 B 0 B / +0.0% 1.938 s -117.8 ms / -5.7% (better) 6.729 ms +331.2 us / +5.2% (worse)
Windows MinGW ARM64 cprintf-lto 43520 B 0 B / +0.0% 4340 B 0 B / +0.0% 2.000 s +60.29 ms / +3.1% (worse) 6.437 ms -212.2 us / -3.2% (better)
Windows MinGW ARM64 fmtprintf 5342720 B 0 B / +0.0% 510688 B 0 B / +0.0% 7.091 s -135.2 ms / -1.9% (better) 13.324 ms -392.2 us / -2.9% (better)
Windows MinGW ARM64 fmtprintf-lto 4299264 B 0 B / +0.0% 476940 B 0 B / +0.0% 14.146 s +85.41 ms / +0.6% (worse) 14.318 ms +178.8 us / +1.3% (worse)
Windows MinGW ARM64 println 712704 B 0 B / +0.0% 23884 B 0 B / +0.0% 1.951 s +23.06 ms / +1.2% (worse) 11.460 ms -322.6 us / -2.7% (better)
Windows MinGW ARM64 println-lto 215552 B 0 B / +0.0% 21232 B 0 B / +0.0% 2.197 s -36.06 ms / -1.6% (better) 10.936 ms -1.675 ms / -13.3% (better)
Windows MSVC cprintf 891904 B 0 B / +0.0% 65798 B 0 B / +0.0% 1.235 s -19.29 ms / -1.5% (better) 2.725 ms -43.2 us / -1.6% (better)
Windows MSVC cprintf-lto 289792 B 0 B / +0.0% 65734 B 0 B / +0.0% 1.209 s -151.4 ms / -11.1% (better) 2.786 ms +36.5 us / +1.3% (worse)
Windows MSVC fmtprintf 5732352 B 0 B / +0.0% 695542 B 0 B / +0.0% 5.615 s -572.9 ms / -9.3% (better) 7.084 ms +188.8 us / +2.7% (worse)
Windows MSVC fmtprintf-lto 4448256 B 0 B / +0.0% 645782 B 0 B / +0.0% 11.187 s -471.1 ms / -4.0% (better) 8.130 ms +571.9 us / +7.6% (worse)
Windows MSVC println 1016832 B 0 B / +0.0% 120854 B 0 B / +0.0% 1.199 s -82.48 ms / -6.4% (better) 5.509 ms -467.5 us / -7.8% (better)
Windows MSVC println-lto 528384 B 0 B / +0.0% 118390 B 0 B / +0.0% 1.458 s -55.57 ms / -3.7% (better) 5.550 ms -1.756 ms / -24.0% (better)
Windows MSVC 386 cprintf 512512 B 0 B / +0.0% 3931 B 0 B / +0.0% 1.228 s -3.699 ms / -0.3% (better) 4.521 ms -888.9 us / -16.4% (better)
Windows MSVC 386 cprintf-lto 44032 B 0 B / +0.0% 3853 B 0 B / +0.0% 1.357 s +105.9 ms / +8.5% (worse) 4.490 ms -35.4 us / -0.8% (better)
Windows MSVC 386 fmtprintf 4478464 B 0 B / +0.0% 455692 B 0 B / +0.0% 5.703 s -6.257 ms / -0.1% (better) 10.167 ms +758.9 us / +8.1% (worse)
Windows MSVC 386 fmtprintf-lto 3896832 B 0 B / +0.0% 426395 B 0 B / +0.0% 10.876 s -394 ms / -3.5% (better) 9.328 ms +249.7 us / +2.8% (worse)
Windows MSVC 386 println 566272 B 0 B / +0.0% 20340 B 0 B / +0.0% 1.246 s +623.2 us / +0.1% (worse) 7.906 ms -419.9 us / -5.0% (better)
Windows MSVC 386 println-lto 199168 B 0 B / +0.0% 18501 B 0 B / +0.0% 1.450 s -23.06 ms / -1.6% (better) 8.133 ms +265.2 us / +3.4% (worse)
Windows MSVC ARM64 cprintf 661504 B 0 B / +0.0% 4192 B 0 B / +0.0% 1.520 s -122.4 ms / -7.4% (better) 6.332 ms -308.2 us / -4.6% (better)
Windows MSVC ARM64 cprintf-lto 47616 B 0 B / +0.0% 4084 B 0 B / +0.0% 1.559 s -85.89 ms / -5.2% (better) 7.032 ms -303.3 us / -4.1% (better)
Windows MSVC ARM64 fmtprintf 5338624 B 0 B / +0.0% 510632 B 0 B / +0.0% 6.426 s -48.07 ms / -0.7% (better) 15.151 ms +1.464 ms / +10.7% (worse)
Windows MSVC ARM64 fmtprintf-lto 4305408 B 0 B / +0.0% 477604 B 0 B / +0.0% 13.109 s +615.9 ms / +4.9% (worse) 15.070 ms +2.036 ms / +15.6% (worse)
Windows MSVC ARM64 println 714752 B 0 B / +0.0% 23908 B 0 B / +0.0% 1.573 s -68.04 ms / -4.1% (better) 11.958 ms -547.4 us / -4.4% (better)
Windows MSVC ARM64 println-lto 220160 B 0 B / +0.0% 21380 B 0 B / +0.0% 1.785 s -77.33 ms / -4.2% (better) 10.777 ms -1.363 ms / -11.2% (better)
Core language and compiler benchmarks
Platform Benchmark ns/op vs base
Linux BenchmarkLookupPCRandom 14.720 ns/op -0.06 ns/op / -0.4% (better)
Linux BenchmarkMergeCompilerFlags 202.100 ns/op -0.1 ns/op / -0.04946% (better)
Linux BenchmarkMergeLinkerFlags 137.100 ns/op +3.7 ns/op / +2.8% (worse)
Linux BenchmarkChannelBuffered 55.100 ns/op -0.46 ns/op / -0.8% (better)
Linux BenchmarkChannelHandoff 15395 ns/op +2767 ns/op / +21.9% (worse)
Linux BenchmarkDefer 51.760 ns/op +0.04 ns/op / +0.1% (worse)
Linux BenchmarkDirectCall 1.601 ns/op -0.006 ns/op / -0.4% (better)
Linux BenchmarkGlobalRead 1.163 ns/op -0.006 ns/op / -0.5% (better)
Linux BenchmarkGlobalWrite 7.769 ns/op +0.005 ns/op / +0.1% (worse)
Linux BenchmarkGoroutine 33469 ns/op +3080 ns/op / +10.1% (worse)
Linux BenchmarkInterfaceCall 5.851 ns/op -0.009 ns/op / -0.2% (better)
Linux BenchmarkRuntimeGetG 2.375 ns/op +0.02 ns/op / +0.8% (worse)
macOS BenchmarkLookupPCRandom 12.440 ns/op -5.62 ns/op / -31.1% (better)
macOS BenchmarkMergeCompilerFlags 132.300 ns/op -34.4 ns/op / -20.6% (better)
macOS BenchmarkMergeLinkerFlags 103.800 ns/op -0.5 ns/op / -0.5% (better)
macOS BenchmarkChannelBuffered 32.590 ns/op -4.06 ns/op / -11.1% (better)
macOS BenchmarkChannelHandoff 9776 ns/op -2672 ns/op / -21.5% (better)
macOS BenchmarkDefer 45.140 ns/op -1.23 ns/op / -2.7% (better)
macOS BenchmarkDirectCall 1.379 ns/op +0.081 ns/op / +6.2% (worse)
macOS BenchmarkGlobalRead 1.250 ns/op -0.041 ns/op / -3.2% (better)
macOS BenchmarkGlobalWrite 1.247 ns/op -0.261 ns/op / -17.3% (better)
macOS BenchmarkGoroutine 67283 ns/op +24292 ns/op / +56.5% (worse)
macOS BenchmarkInterfaceCall 5.118 ns/op +0.209 ns/op / +4.3% (worse)
macOS BenchmarkRuntimeGetG 2.676 ns/op -0.338 ns/op / -11.2% (better)
Windows MinGW BenchmarkLookupPCRandom 13.150 ns/op +0.03 ns/op / +0.2% (worse)
Windows MinGW BenchmarkMergeCompilerFlags 619.900 ns/op -36.3 ns/op / -5.5% (better)
Windows MinGW BenchmarkMergeLinkerFlags 560.400 ns/op -22.8 ns/op / -3.9% (better)
Windows MinGW BenchmarkChannelBuffered 30.930 ns/op +0.36 ns/op / +1.2% (worse)
Windows MinGW BenchmarkChannelHandoff 922.700 ns/op -31.8 ns/op / -3.3% (better)
Windows MinGW BenchmarkDefer 58.030 ns/op -0.35 ns/op / -0.6% (better)
Windows MinGW BenchmarkDirectCall 1.548 ns/op +0.002 ns/op / +0.1% (worse)
Windows MinGW BenchmarkGlobalRead 1.547 ns/op 0 ns/op / +0.0%
Windows MinGW BenchmarkGlobalWrite 2.467 ns/op -0.005 ns/op / -0.2% (better)
Windows MinGW BenchmarkGoroutine 94668 ns/op +1093 ns/op / +1.2% (worse)
Windows MinGW BenchmarkInterfaceCall 8.383 ns/op -0.401 ns/op / -4.6% (better)
Windows MinGW BenchmarkRuntimeGetG 2.479 ns/op -0.001 ns/op / -0.04032% (better)
Windows MinGW 386 BenchmarkLookupPCRandom 26.810 ns/op +0.14 ns/op / +0.5% (worse)
Windows MinGW 386 BenchmarkMergeCompilerFlags 803.100 ns/op -33.9 ns/op / -4.1% (better)
Windows MinGW 386 BenchmarkMergeLinkerFlags 694.800 ns/op -22.6 ns/op / -3.2% (better)
Windows MinGW 386 BenchmarkChannelBuffered 42 ns/op +0.57 ns/op / +1.4% (worse)
Windows MinGW 386 BenchmarkChannelHandoff 781.400 ns/op -168.8 ns/op / -17.8% (better)
Windows MinGW 386 BenchmarkDefer 48.530 ns/op +3 ns/op / +6.6% (worse)
Windows MinGW 386 BenchmarkDirectCall 1.586 ns/op +0.03 ns/op / +1.9% (worse)
Windows MinGW 386 BenchmarkGlobalRead 1.552 ns/op -0.004 ns/op / -0.3% (better)
Windows MinGW 386 BenchmarkGlobalWrite 7.797 ns/op +0.02 ns/op / +0.3% (worse)
Windows MinGW 386 BenchmarkGoroutine 109909 ns/op +74 ns/op / +0.1% (worse)
Windows MinGW 386 BenchmarkInterfaceCall 8.509 ns/op +0.04 ns/op / +0.5% (worse)
Windows MinGW 386 BenchmarkRuntimeGetG 1.933 ns/op +0.002 ns/op / +0.1% (worse)
Windows MinGW ARM64 BenchmarkLookupPCRandom 12.120 ns/op 0 ns/op / +0.0%
Windows MinGW ARM64 BenchmarkMergeCompilerFlags 583.100 ns/op +4.1 ns/op / +0.7% (worse)
Windows MinGW ARM64 BenchmarkMergeLinkerFlags 539.100 ns/op -3.3 ns/op / -0.6% (better)
Windows MinGW ARM64 BenchmarkChannelBuffered 39.080 ns/op +1.2 ns/op / +3.2% (worse)
Windows MinGW ARM64 BenchmarkChannelHandoff 2207 ns/op +434 ns/op / +24.5% (worse)
Windows MinGW ARM64 BenchmarkDefer 59.030 ns/op +3.98 ns/op / +7.2% (worse)
Windows MinGW ARM64 BenchmarkDirectCall 0.663 ns/op -0.0006 ns/op / -0.1% (better)
Windows MinGW ARM64 BenchmarkGlobalRead 0.664 ns/op +0.0005 ns/op / +0.1% (worse)
Windows MinGW ARM64 BenchmarkGlobalWrite 0.737 ns/op 0 ns/op / +0.0%
Windows MinGW ARM64 BenchmarkGoroutine 64672 ns/op -164 ns/op / -0.3% (better)
Windows MinGW ARM64 BenchmarkInterfaceCall 4.141 ns/op -0.015 ns/op / -0.4% (better)
Windows MinGW ARM64 BenchmarkRuntimeGetG 1.769 ns/op -0.001 ns/op / -0.1% (better)
Windows MSVC BenchmarkLookupPCRandom 9.571 ns/op +0.022 ns/op / +0.2% (worse)
Windows MSVC BenchmarkMergeCompilerFlags 379.200 ns/op +8.5 ns/op / +2.3% (worse)
Windows MSVC BenchmarkMergeLinkerFlags 329.900 ns/op -6.6 ns/op / -2.0% (better)
Windows MSVC BenchmarkChannelBuffered 23.950 ns/op -0.22 ns/op / -0.9% (better)
Windows MSVC BenchmarkChannelHandoff 988.100 ns/op -34.9 ns/op / -3.4% (better)
Windows MSVC BenchmarkDefer 43.730 ns/op -0.01 ns/op / -0.02286% (better)
Windows MSVC BenchmarkDirectCall 1.356 ns/op -0.002 ns/op / -0.1% (better)
Windows MSVC BenchmarkGlobalRead 1.357 ns/op -0.001 ns/op / -0.1% (better)
Windows MSVC BenchmarkGlobalWrite 2.164 ns/op -0.004 ns/op / -0.2% (better)
Windows MSVC BenchmarkGoroutine 57453 ns/op +774 ns/op / +1.4% (worse)
Windows MSVC BenchmarkInterfaceCall 7.335 ns/op -0.017 ns/op / -0.2% (better)
Windows MSVC BenchmarkRuntimeGetG 1.901 ns/op 0 ns/op / +0.0%
Windows MSVC 386 BenchmarkLookupPCRandom 21.560 ns/op +0.02 ns/op / +0.1% (worse)
Windows MSVC 386 BenchmarkMergeCompilerFlags 562.300 ns/op -30 ns/op / -5.1% (better)
Windows MSVC 386 BenchmarkMergeLinkerFlags 517.600 ns/op -13.9 ns/op / -2.6% (better)
Windows MSVC 386 BenchmarkChannelBuffered 34.040 ns/op +0.17 ns/op / +0.5% (worse)
Windows MSVC 386 BenchmarkChannelHandoff 693.800 ns/op -14.2 ns/op / -2.0% (better)
Windows MSVC 386 BenchmarkDefer 38.630 ns/op -1.41 ns/op / -3.5% (better)
Windows MSVC 386 BenchmarkDirectCall 1.358 ns/op +0.001 ns/op / +0.1% (worse)
Windows MSVC 386 BenchmarkGlobalRead 1.358 ns/op -0.001 ns/op / -0.1% (better)
Windows MSVC 386 BenchmarkGlobalWrite 6.979 ns/op -0.006 ns/op / -0.1% (better)
Windows MSVC 386 BenchmarkGoroutine 72003 ns/op -1015 ns/op / -1.4% (better)
Windows MSVC 386 BenchmarkInterfaceCall 7.333 ns/op -0.011 ns/op / -0.1% (better)
Windows MSVC 386 BenchmarkRuntimeGetG 1.632 ns/op 0 ns/op / +0.0%
Windows MSVC ARM64 BenchmarkLookupPCRandom 12.130 ns/op -0.01 ns/op / -0.1% (better)
Windows MSVC ARM64 BenchmarkMergeCompilerFlags 587.100 ns/op +7.4 ns/op / +1.3% (worse)
Windows MSVC ARM64 BenchmarkMergeLinkerFlags 547.200 ns/op -4.9 ns/op / -0.9% (better)
Windows MSVC ARM64 BenchmarkChannelBuffered 38.500 ns/op +0.95 ns/op / +2.5% (worse)
Windows MSVC ARM64 BenchmarkChannelHandoff 3855 ns/op +267 ns/op / +7.4% (worse)
Windows MSVC ARM64 BenchmarkDefer 59.200 ns/op +0.01 ns/op / +0.01689% (worse)
Windows MSVC ARM64 BenchmarkDirectCall 0.664 ns/op +0.0002 ns/op / +0.03015% (worse)
Windows MSVC ARM64 BenchmarkGlobalRead 0.663 ns/op -0.0005 ns/op / -0.1% (better)
Windows MSVC ARM64 BenchmarkGlobalWrite 3.795 ns/op 0 ns/op / +0.0%
Windows MSVC ARM64 BenchmarkGoroutine 59732 ns/op +2898 ns/op / +5.1% (worse)
Windows MSVC ARM64 BenchmarkInterfaceCall 4.141 ns/op +0.002 ns/op / +0.04832% (worse)
Windows MSVC ARM64 BenchmarkRuntimeGetG 1.770 ns/op -0.012 ns/op / -0.7% (better)
Timer runtime benchmarks
Platform Operation and runtime ns/op vs base
Linux AfterFuncZeroDelivery/Go 926.200 ns/op -80.8 ns/op / -8.0% (better)
Linux AfterFuncZeroDelivery/LLGo 45237 ns/op +4539 ns/op / +11.2% (worse)
Linux CreateStop/Go 306 ns/op +2.5 ns/op / +0.8% (worse)
Linux CreateStop/LLGo 1938 ns/op +44 ns/op / +2.3% (worse)
Linux RearmStopped/Go 116.300 ns/op +0.1 ns/op / +0.1% (worse)
Linux RearmStopped/LLGo 1479 ns/op -39 ns/op / -2.6% (better)
Linux ResetActive/Go 68.880 ns/op +0.16 ns/op / +0.2% (worse)
Linux ResetActive/LLGo 780.600 ns/op -14.4 ns/op / -1.8% (better)
Linux ResetHeap1024/Go 67.190 ns/op -0.07 ns/op / -0.1% (better)
Linux ResetHeap1024/LLGo 182.500 ns/op -3.4 ns/op / -1.8% (better)
macOS AfterFuncZeroDelivery/Go 858 ns/op +157 ns/op / +22.4% (worse)
macOS AfterFuncZeroDelivery/LLGo 138679 ns/op +34527 ns/op / +33.2% (worse)
macOS CreateStop/Go 142.700 ns/op -30.1 ns/op / -17.4% (better)
macOS CreateStop/LLGo 875.800 ns/op +430.2 ns/op / +96.5% (worse)
macOS RearmStopped/Go 70.240 ns/op -6.13 ns/op / -8.0% (better)
macOS RearmStopped/LLGo 444.700 ns/op -241.6 ns/op / -35.2% (better)
macOS ResetActive/Go 50.750 ns/op -5.74 ns/op / -10.2% (better)
macOS ResetActive/LLGo 169.600 ns/op -135.4 ns/op / -44.4% (better)
macOS ResetHeap1024/Go 77.160 ns/op +17.19 ns/op / +28.7% (worse)
macOS ResetHeap1024/LLGo 130.900 ns/op +17.7 ns/op / +15.6% (worse)
Windows MinGW AfterFuncZeroDelivery/Go 546.800 ns/op -42.1 ns/op / -7.1% (better)
Windows MinGW AfterFuncZeroDelivery/LLGo 183812 ns/op +903 ns/op / +0.5% (worse)
Windows MinGW CreateStop/Go 118 ns/op -1.6 ns/op / -1.3% (better)
Windows MinGW CreateStop/LLGo 422.300 ns/op +9.4 ns/op / +2.3% (worse)
Windows MinGW RearmStopped/Go 31.620 ns/op -0.03 ns/op / -0.1% (better)
Windows MinGW RearmStopped/LLGo 276.800 ns/op +6.4 ns/op / +2.4% (worse)
Windows MinGW ResetActive/Go 20.070 ns/op -0.01 ns/op / -0.0498% (better)
Windows MinGW ResetActive/LLGo 163.500 ns/op -2.2 ns/op / -1.3% (better)
Windows MinGW ResetHeap1024/Go 20.480 ns/op -0.16 ns/op / -0.8% (better)
Windows MinGW ResetHeap1024/LLGo 128 ns/op +2.1 ns/op / +1.7% (worse)
Windows MinGW 386 AfterFuncZeroDelivery/Go 985.200 ns/op +26.7 ns/op / +2.8% (worse)
Windows MinGW 386 AfterFuncZeroDelivery/LLGo 199530 ns/op +3029 ns/op / +1.5% (worse)
Windows MinGW 386 CreateStop/Go 197.200 ns/op +2.4 ns/op / +1.2% (worse)
Windows MinGW 386 CreateStop/LLGo 572.400 ns/op +40 ns/op / +7.5% (worse)
Windows MinGW 386 RearmStopped/Go 64.220 ns/op +0.6 ns/op / +0.9% (worse)
Windows MinGW 386 RearmStopped/LLGo 364.900 ns/op +3.7 ns/op / +1.0% (worse)
Windows MinGW 386 ResetActive/Go 40.590 ns/op +1.35 ns/op / +3.4% (worse)
Windows MinGW 386 ResetActive/LLGo 1033 ns/op +9 ns/op / +0.9% (worse)
Windows MinGW 386 ResetHeap1024/Go 40.320 ns/op +0.43 ns/op / +1.1% (worse)
Windows MinGW 386 ResetHeap1024/LLGo 190.400 ns/op +2.2 ns/op / +1.2% (worse)
Windows MinGW ARM64 AfterFuncZeroDelivery/Go 663.200 ns/op +0.3 ns/op / +0.04526% (worse)
Windows MinGW ARM64 AfterFuncZeroDelivery/LLGo 151248 ns/op +2143 ns/op / +1.4% (worse)
Windows MinGW ARM64 CreateStop/Go 204.100 ns/op -8.8 ns/op / -4.1% (better)
Windows MinGW ARM64 CreateStop/LLGo 388.900 ns/op +11 ns/op / +2.9% (worse)
Windows MinGW ARM64 RearmStopped/Go 70.550 ns/op -0.03 ns/op / -0.0425% (better)
Windows MinGW ARM64 RearmStopped/LLGo 260.100 ns/op +3.5 ns/op / +1.4% (worse)
Windows MinGW ARM64 ResetActive/Go 31.070 ns/op +0.09 ns/op / +0.3% (worse)
Windows MinGW ARM64 ResetActive/LLGo 131.500 ns/op +4.9 ns/op / +3.9% (worse)
Windows MinGW ARM64 ResetHeap1024/Go 31.130 ns/op +0.02 ns/op / +0.1% (worse)
Windows MinGW ARM64 ResetHeap1024/LLGo 125.200 ns/op +0.7 ns/op / +0.6% (worse)
Windows MSVC AfterFuncZeroDelivery/Go 382.200 ns/op +2.3 ns/op / +0.6% (worse)
Windows MSVC AfterFuncZeroDelivery/LLGo 110455 ns/op -57 ns/op / -0.1% (better)
Windows MSVC CreateStop/Go 89.620 ns/op -2.23 ns/op / -2.4% (better)
Windows MSVC CreateStop/LLGo 356.900 ns/op +11.7 ns/op / +3.4% (worse)
Windows MSVC RearmStopped/Go 24.440 ns/op 0 ns/op / +0.0%
Windows MSVC RearmStopped/LLGo 229.100 ns/op +4.7 ns/op / +2.1% (worse)
Windows MSVC ResetActive/Go 14.800 ns/op +0.02 ns/op / +0.1% (worse)
Windows MSVC ResetActive/LLGo 114 ns/op -1 ns/op / -0.9% (better)
Windows MSVC ResetHeap1024/Go 14.790 ns/op -0.03 ns/op / -0.2% (better)
Windows MSVC ResetHeap1024/LLGo 104.100 ns/op -0.2 ns/op / -0.2% (better)
Windows MSVC 386 AfterFuncZeroDelivery/Go 777.400 ns/op -1.2 ns/op / -0.2% (better)
Windows MSVC 386 AfterFuncZeroDelivery/LLGo 129875 ns/op -283 ns/op / -0.2% (better)
Windows MSVC 386 CreateStop/Go 173.800 ns/op +0.6 ns/op / +0.3% (worse)
Windows MSVC 386 CreateStop/LLGo 404.400 ns/op +41.7 ns/op / +11.5% (worse)
Windows MSVC 386 RearmStopped/Go 56.670 ns/op -0.32 ns/op / -0.6% (better)
Windows MSVC 386 RearmStopped/LLGo 265.600 ns/op +2.9 ns/op / +1.1% (worse)
Windows MSVC 386 ResetActive/Go 32.540 ns/op -0.09 ns/op / -0.3% (better)
Windows MSVC 386 ResetActive/LLGo 212.300 ns/op -678 ns/op / -76.2% (better)
Windows MSVC 386 ResetHeap1024/Go 32.820 ns/op 0 ns/op / +0.0%
Windows MSVC 386 ResetHeap1024/LLGo 142.100 ns/op -0.2 ns/op / -0.1% (better)
Windows MSVC ARM64 AfterFuncZeroDelivery/Go 675.900 ns/op +8.7 ns/op / +1.3% (worse)
Windows MSVC ARM64 AfterFuncZeroDelivery/LLGo 164939 ns/op -1076 ns/op / -0.6% (better)
Windows MSVC ARM64 CreateStop/Go 200 ns/op -3.3 ns/op / -1.6% (better)
Windows MSVC ARM64 CreateStop/LLGo 379.800 ns/op +0.1 ns/op / +0.02634% (worse)
Windows MSVC ARM64 RearmStopped/Go 70.540 ns/op -0.09 ns/op / -0.1% (better)
Windows MSVC ARM64 RearmStopped/LLGo 266.900 ns/op -2.5 ns/op / -0.9% (better)
Windows MSVC ARM64 ResetActive/Go 30.870 ns/op -0.02 ns/op / -0.1% (better)
Windows MSVC ARM64 ResetActive/LLGo 126.400 ns/op -5.5 ns/op / -4.2% (better)
Windows MSVC ARM64 ResetHeap1024/Go 31.110 ns/op +0.18 ns/op / +0.6% (worse)
Windows MSVC ARM64 ResetHeap1024/LLGo 135 ns/op -1.1 ns/op / -0.8% (better)

Compared with d98b43f90a3d measured in the same runner job.

@cpunion cpunion changed the title debug: allow supported targets to retain DWARF debug: unify artifacts and native/embedded sessions Sep 30, 2026
@cpunion
cpunion force-pushed the codex/debug-artifact-policy-2164-20260801 branch from a16528c to 664b553 Compare September 30, 2026 21:43
@cpunion
cpunion marked this pull request as ready for review September 30, 2026 21:44
@cpunion
cpunion force-pushed the codex/debug-artifact-policy-2164-20260801 branch from 664b553 to fb8eda4 Compare September 30, 2026 21:50
@cpunion
cpunion force-pushed the codex/debug-artifact-policy-2164-20260801 branch from 421e68e to b486675 Compare September 30, 2026 22:43
@github-actions

github-actions Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

LLGo WebAssembly build benchmarks

c0263bf07eaf | workflow run | long-term charts

WebAssembly output sizes
Example, profile and compiler Wasm module vs base Generated JS glue vs base
cprintf/j32-emscripten/LLGo 154193 B 0 B / +0.0% 88742 B 0 B / +0.0%
cprintf/j32-goos-js/LLGo 152295 B 0 B / +0.0% 73165 B 0 B / +0.0%
cprintf/j64-emscripten-memory64/LLGo 141248 B 0 B / +0.0% 92630 B 0 B / +0.0%
cprintf/w32-goos-wasip1/LLGo 152848 B 0 B / +0.0% 0 B 0 B / 0.0%
cprintf/w32-wasi/LLGo 153560 B 0 B / +0.0% 0 B 0 B / 0.0%
fmtprintf/j32-emscripten/LLGo 3213428 B 0 B / +0.0% 132442 B 0 B / +0.0%
fmtprintf/j32-goos-js/Go 2526852 B 0 B / +0.0% 0 B 0 B / 0.0%
fmtprintf/j32-goos-js/LLGo 3192523 B 0 B / +0.0% 101635 B 0 B / +0.0%
fmtprintf/j64-emscripten-memory64/LLGo 2950033 B 0 B / +0.0% 139285 B 0 B / +0.0%
fmtprintf/w32-goos-wasip1/Go 2500019 B 0 B / +0.0% 0 B 0 B / 0.0%
fmtprintf/w32-goos-wasip1/LLGo 2347351 B 0 B / +0.0% 0 B 0 B / 0.0%
fmtprintf/w32-wasi/LLGo 2344013 B 0 B / +0.0% 0 B 0 B / 0.0%
j32-emscripten/LLGo 153428 B 0 B / +0.0% 88742 B 0 B / +0.0%
j32-goos-js/Go 1895533 B 0 B / +0.0% 0 B 0 B / 0.0%
j32-goos-js/LLGo 151768 B 0 B / +0.0% 73165 B 0 B / +0.0%
j64-emscripten-memory64/LLGo 140582 B 0 B / +0.0% 92630 B 0 B / +0.0%
reflectcall/j32-emscripten/LLGo 1543771 B 0 B / +0.0% 105908 B 0 B / +0.0%
reflectcall/j32-goos-js/Go 2191221 B 0 B / +0.0% 0 B 0 B / 0.0%
reflectcall/j32-goos-js/LLGo 1546222 B 0 B / +0.0% 90331 B 0 B / +0.0%
reflectcall/j64-emscripten-memory64/LLGo 1428426 B 0 B / +0.0% 111641 B 0 B / +0.0%
reflectcall/w32-goos-wasip1/Go 2205707 B 0 B / +0.0% 0 B 0 B / 0.0%
reflectcall/w32-goos-wasip1/LLGo 1276693 B 0 B / +0.0% 0 B 0 B / 0.0%
reflectcall/w32-wasi/LLGo 1274301 B 0 B / +0.0% 0 B 0 B / 0.0%
w32-goos-wasip1/Go 1909947 B 0 B / +0.0% 0 B 0 B / 0.0%
w32-goos-wasip1/LLGo 152495 B 0 B / +0.0% 0 B 0 B / 0.0%
w32-wasi/LLGo 153207 B 0 B / +0.0% 0 B 0 B / 0.0%
LLGo WebAssembly build measurements
Example and profile Build vs base
j32-emscripten 6.270 s +136.1 ms / +2.2% (worse)
j32-goos-js 6.046 s +59.6 ms / +1.0% (worse)
j64-emscripten-memory64 5.804 s +303.1 ms / +5.5% (worse)
reflectcall/w32-wasi 23.653 s -933 ms / -3.8% (better)
w32-goos-wasip1 4.325 s +29.37 ms / +0.7% (worse)
w32-wasi 4.108 s +127.4 ms / +3.2% (worse)

Compared with d98b43f90a3d measured in the same runner job.

@cpunion
cpunion force-pushed the codex/debug-artifact-policy-2164-20260801 branch 3 times, most recently from 7d0081e to f34d646 Compare October 1, 2026 09:27
@cpunion
cpunion force-pushed the codex/debug-artifact-policy-2164-20260801 branch 3 times, most recently from 7355101 to 001190d Compare October 1, 2026 19:01
@cpunion
cpunion force-pushed the codex/debug-artifact-policy-2164-20260801 branch from 57db254 to c0263bf Compare October 1, 2026 19:32

@visualfc visualfc left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review

Artifact roles, llgo debug DWARF/-O0 policy, host-ELF vs flash images, and Wasm sidecar pairing look solid. Default target builds still omit DWARF, so hello-world size is unchanged.

P2 items below can break a production QEMU/OpenOCD session or Windows Wasm rewrite. CI currently hides the empty-probe case behind qemu_load_proxy.py.

}
connection, err := net.DialTimeout("tcp", address, 100*time.Millisecond)
if err == nil {
connection.Close()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Empty TCP probe can consume the GDB stub connection

waitReady dials the gdb port, sends no RSP, and closes. test/debug/embedded/qemu_load_proxy.py exists specifically for this (llgo probes readiness without sending an RSP packet and skips an empty first recv).

Production llgo debug -target=cortex-m-qemu talks to QEMU -gdb tcp: directly, without that proxy. Many stubs accept one client; this probe can take the only slot or reset the stub before GDB/LLDB attach.

Prefer a ready signal that is not the gdb port, or keep the probe from acting as a GDB client.

}

func freeTCPPort() (int, error) {
listener, err := net.Listen("tcp", "127.0.0.1:0")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Port is released before QEMU/OpenOCD bind

freeTCPPort listens on :0, closes, then the port is interpolated into gdb_port / -gdb tcp:127.0.0.1:{debug-port}. Another process can take the port in between, so debug-server startup fails intermittently.

Have the server pick the port and parse it from logs, or pass a still-open listener.

if err := tmp.Close(); err != nil {
return err
}
return os.Rename(tmpPath, path)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] os.Rename cannot replace an existing file on Windows

This helper rewrites the live .wasm (and the sidecar). Unix rename replaces the destination; Windows os.Rename fails when path already exists. external/embedded Wasm packaging will error on Windows after the first write of modulePath.

Remove path before rename, or fall back when Rename fails with os.ErrExist.

goos, goarch, llvmTarget = target.GOOS, target.GOARCH, target.LLVMTarget
}
if goarch == "wasm" || strings.HasPrefix(llvmTarget, "wasm") {
if goos == "js" || strings.HasPrefix(conf.Target, "wasm") {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P3] Target names starting with wasm are classified as browser

strings.HasPrefix(conf.Target, "wasm") sends wasm-unknown (and any WASI target named wasm*) to backendBrowser, which then errors as unimplemented. The unit test uses Target: "wasm" with GOOS: "js", so the prefix check is what decides browser.

Classify from GOOS == "js" / the Wasm profile instead of the target name prefix.


// Cmd is the llgo debug command.
var Cmd = &base.Command{
UsageLine: "llgo debug [-backend auto|lldb|gdb|wasmtime|browser] [-target platform] [build flags] [package] [-- debugger arguments...]",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P3] Help lists wasmtime/browser backends that immediately error

UsageLine advertises -backend auto|lldb|gdb|wasmtime|browser. Selecting wasmtime or browser returns not available yet. Docs call them reserved; the flag help still looks implemented. cmd/llgo/debug_cmd.gox repeats the same usage string.

Keep auto/lldb/gdb in UsageLine, and mention the reserved backends in the long help.

func EnsureBuildID(module []byte) ([]byte, []byte, error) {
if id, ok, err := BuildID(module); err != nil {
return nil, nil, err
} else if ok {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P3] Existing build_id does not cover the debugger ABI section

finalizeDebugArtifact runs SetDebuggerRecord then EnsureBuildID. If the linker already emitted build_id, this branch keeps it, so the id does not hash the ABI record that was just added. When no id is present, SHA-256 is over the full module, including that record.

Sidecar pairing still matches (same bytes on both modules). Stale-sidecar checks that treat build_id as a content identity will not see ABI-section edits. Recompute, or hash after the ABI write.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants