Skip to content

fix: size heap allocations with sizeof(T), unblocking aether v0.643.0 - #107

Merged
paul-hammant merged 1 commit into
mainfrom
fix/sizeof-heap-allocs-0643
Sep 6, 2026
Merged

fix: size heap allocations with sizeof(T), unblocking aether v0.643.0#107
paul-hammant merged 1 commit into
mainfrom
fix/sizeof-heap-allocs-0643

Conversation

@paul-hammant

Copy link
Copy Markdown
Collaborator

What

Bump the CI toolchain pins aether v0.627.0 → v0.643.0 and aeb v0.283 → v0.296, and make the source change that the aether bump requires.

Why it wasn't a one-line pin bump

Pinning to aether 0.643.0 turned 14 pure-Aether vg/ unit suites red with glibc heap-corruption aborts (malloc assertion failure in sysmalloc, malloc(): invalid size, free(): invalid pointer — three different detectors, i.e. general metadata corruption).

Bisected to aether commit 1307dfa8 (first commit after v0.642.0, "Place heap trackers inline so struct-prefix punning stays sound"). It moves the hidden int _heap_<field> string-ownership trackers from a trailing block to inline (right after each string field). That's a correct fix for the punning bug it targets, but it grows the sizeof of any pure-Aether struct whose string field isn't last.

This repo allocated ~158 structs with a hand-computed byte count (malloc(40) as *SvgNode), each sized for the old trailing layout. Under inline layout every one under-allocates by an int, and the final tracker store runs off the end of the block. ASan pinpointed it: a 4-byte heap-buffer-overflow in SvgNode (needs 48 bytes, we malloc'd 40).

aether vg/test/test_parser
v0.641.0 passed
v0.642.0 passed
v0.643.0 abort (rc 134)
1307dfa8 direct abort — culprit confirmed

The fix

Swept all 158 sites malloc(N)malloc(sizeof(T)) across vg/, ui/, apps/, examples/ (98 files). sizeof is layout-exact and ≥ the old count, so it's correct under both the old and new tracker layouts and immune to any future placement change. Raw malloc(8) byte buffers (no struct cast) left untouched. This also hardens against the earlier 0.624.0 setter-tracker class (#1866), since the boxes are now correctly sized.

Verification

  • Full local matrix all-green on 0.643.0 + aeb v0.296 (=== CI result: all phases passed ===).
  • The 14 previously-crashing vg suites all pass.
  • aeb is not implicated — the failing suites compile via aetherc + gcc with no aeb in the loop; the aeb bump was verified independently building the whole fan-out.

For the aether line

asks/REGRESSION-0643-inline-heap-tracker-grows-struct.md — full bisect, ASan output, 30-second reproducer, plus a design question (should inline placement preserve total struct size? could the compiler lint malloc(literal) < sizeof(cast target)?). Framed as FYI, not a revert request.

🤖 Generated with Claude Code

aether 0.643.0 (commit 1307dfa8) moves the hidden `int _heap_<field>`
string-ownership trackers from a trailing block to inline, immediately
after each string field. That grows the sizeof of pure-Aether structs
whose string field isn't last — and this repo allocated ~158 structs
with a hand-computed byte count (`malloc(40) as *SvgNode`) sized for the
old trailing layout. Every one under-allocated by an int under the new
layout, and the final tracker store ran off the end of the block:
ASan shows a 4-byte heap-buffer-overflow in SvgNode (needs 48, we
malloc'd 40), surfacing as glibc `malloc assertion failure in sysmalloc`
/ `invalid size` / `free(): invalid pointer` across 14 vg unit suites.

Bisected 0.641 GOOD / 0.642 GOOD / 0.643 BAD; culprit confirmed by
building 1307dfa8 directly.

Fix: sweep all 158 sites `malloc(N)` -> `malloc(sizeof(T))`, across
vg/, ui/, apps/ and examples/. sizeof is layout-exact and >= the old
count, so it is correct under both the old and new tracker layouts and
immune to any future placement change. Raw `malloc(8)` byte buffers with
no struct cast are left untouched. This also hardens against the earlier
0.624.0 setter-tracker class (#1866): the boxes are now correctly sized.

Pins moved together and re-verified all-green on the local matrix:
- AETHER_REF v0.627.0 -> v0.643.0
- AEB_REF    v0.283   -> v0.296  (aeb is not implicated; the failing
  suites compile via aetherc + gcc with no aeb in the loop)

Regression documented for the aether line in
asks/REGRESSION-0643-inline-heap-tracker-grows-struct.md (bisect, ASan,
reproducer, and a design question on size-stability / a malloc-size lint).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q5pckLB6QCPfjVQAYcE9LZ
@paul-hammant
paul-hammant merged commit b507122 into main Sep 6, 2026
3 checks passed
@paul-hammant
paul-hammant deleted the fix/sizeof-heap-allocs-0643 branch September 6, 2026 10:59
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.

1 participant