Skip to content

feat(variables): add -O2 fixture for broader location coverage - #1042

Open
JoshuaMoelans wants to merge 5 commits into
joshua/test/variables_fixturefrom
joshua/test/fixture_O2
Open

feat(variables): add -O2 fixture for broader location coverage#1042
JoshuaMoelans wants to merge 5 commits into
joshua/test/variables_fixturefrom
joshua/test/fixture_O2

Conversation

@JoshuaMoelans

@JoshuaMoelans JoshuaMoelans commented Aug 13, 2026

Copy link
Copy Markdown
Member

This branch adds an optimized (-O2) build of the variables fixture, to be merged in on top of #1038 . variables.c is now compiled twice from the same source — fixtures/linux/variables (-O0, unchanged coverage) and fixtures/linux/variables_opt — with the new binary asserted by test_elf_variables_opt and its own snapshot.

The -O2 snapshot covers the location shapes that can't exist at -O0, where everything is a single whole-function stack slot:

  • register locations, both general-purpose and SSE (float_registers shows DWARF regs 17+)
  • ranges shorter than the function, and multi-range location lists (external_call's parameter moves rdi → rbp to survive the rand() call)
  • a frame-base location under optimization, via a volatile local in stack_home

Keeping variables alive at -O2 needs some scaffolding (NOINLINE, an opaque volatile global, and empty-asm USE/USE_F markers), all of it a no-op at -O0. The non-obvious pitfalls we hit are written up in the README — e.g. calls within the same file don't split live ranges because GCC sees the callee's real register usage, so multi-range lists need an external call.

The snapshots also record a few things symbolic doesn't extract yet, so future support shows up as a visible diff: variables reduced to DW_AT_const_value (present at -O0, silently absent at -O2), DW_OP_entry_value/DW_OP_stack_value location entries (already in the fixture's DWARF, currently dropped — it's why parameters end early in the optimized snapshot), and volatile-qualified types rendering as Unknown.

JoshuaMoelans and others added 2 commits August 13, 2026 14:28
variables_opt.c is a separate -O2 companion to variables.c, targeting
the location shapes that cannot occur at -O0: register locations,
sub-function ranges, and multi-range location lists (external_call's
parameter moves rdi -> rbp across the rand() call). Liveness scaffolding
uses noinline, a volatile input global, and an empty-asm USE(x) marker.

Notable finds recorded in the snapshot/README:
- same-TU calls don't split live ranges (GCC IPA-RA sees real clobbers);
  an external call is needed for multi-range lists
- variables optimized to DW_AT_const_value are dropped by symbolic
  entirely (no empty entry), documented as a known gap

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Merge variables_opt.c into variables.c and compile the single source at
both -O0 and -O2, per team decision: one source of truth, two fixture
binaries, two snapshots.

The liveness scaffolding (NOINLINE, opaque, USE) is a no-op at -O0, so
the -O0 snapshot diff is purely additive: the location-oriented
functions gain ordinary stack slots (including `gone`, whose -O0
presence now contrasts directly with its -O2 absence). The existing
type-oriented functions get NOINLINE so -O2 cannot inline them into
main; unscaffolded, they render (nearly) empty in the optimized
snapshot, deliberately recording what optimization does to them.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Comment thread symbolic-debuginfo/tests/test_objects.rs
Trim redundant framing and align the text with the merged single-source
setup (two builds of variables.c, two snapshots). Expand the multi-range
bullet to spell out why same-file calls do not split live ranges: GCC's
interprocedural register allocation sees the callee's real clobbers, so
multi-range coverage needs calls to external functions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@JoshuaMoelans
JoshuaMoelans force-pushed the joshua/test/fixture_O2 branch from 3de1e12 to 8b7afc9 Compare August 14, 2026 10:06
JoshuaMoelans and others added 2 commits August 14, 2026 12:27
Add float_registers (USE_F, an SSE "x"-constraint variant of USE, since
"r" only fits general-purpose registers) asserting DWARF registers 17+,
and stack_home, whose volatile local keeps a frame-base location even at
-O2. The volatile qualifier also reveals another type gap: it wraps the
type in a DW_TAG_volatile_type that symbolic does not follow yet.

Also correct the scaffolding docs based on a with/without-USE DWARF
comparison: data flow alone keeps these values alive, but without the
register pin GCC describes them as DW_OP_stack_value expressions, which
symbolic drops from the snapshot. Entry-value/stack-value entries turn
out to already exist in the fixture's DWARF (parameter tails in
float_registers), so the README now records them as a present-but-
dropped gap rather than coverage to be provoked later.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@JoshuaMoelans JoshuaMoelans changed the title POC: add -O2 variables fixture for location coverage feat(variables) add -O2 fixture for broader location coverage Aug 14, 2026
@JoshuaMoelans JoshuaMoelans changed the title feat(variables) add -O2 fixture for broader location coverage feat(variables): add -O2 fixture for broader location coverage Aug 14, 2026
@github-actions

Copy link
Copy Markdown
Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Generated by 🚫 dangerJS against d6eac4e

@JoshuaMoelans
JoshuaMoelans marked this pull request as ready for review August 14, 2026 11:04
@JoshuaMoelans
JoshuaMoelans requested a review from a team as a code owner August 14, 2026 11:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant