Skip to content

gc tests: root the key tables in the residual prototype tests (#12137) - #12138

Merged
proggeramlug merged 2 commits into
mainfrom
fix/12137
Oct 7, 2026
Merged

proggeramlug merged 2 commits into
mainfrom
fix/12137

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Closes #12137.

This was a test isolation bug, not a region-manager bug.

  • CopyingNurseryTestGuard starts with an empty root-scanner set. Inside that window the residual-prototype tests call Object.setPrototypeOf/getPrototypeOf on builtin owners, which lazily builds intrinsics and creates key atoms in the thread's atom table (ATOMS, string/intern.rs).
  • Production roots that table through scan_intern_table_roots_mut (intern.rs:589), but the window never registered it. A copying minor freed the atoms while the table still named them.
  • The next intrinsic build (populate_global_this_builtins → canonicalize) then published a canonical key list with freed addresses as keys.
  • key_bytes_hash read a garbage length of about 2 MB and ran off the end of its block into the gap after the 2 MiB region. Since gc: Perry-owned memory for GC arena blocks (2 MiB OS regions, huge pages by complete units) #12132 that gap faults; before, the same read was probably a silent garbage read.
  • With ASLR off it fails every time; with ASLR on it failed 18 of 40 runs when run alone.

The fix registers the atom/intern, shape-table rekey and canonical-keys scanners in these tests, the same set runtime_roots/function_attrs_old_minor.rs uses.

Verification:

Separate note for the shape owner, not fixed here and not shown to cause anything in production: the canonical-keys trie is weak, and young canonical key lists are only pruned at a full collection (young_prune: None at gc/dead_owner.rs:434). A list that dies in a minor stays in the trie until the next full collection.

Ralph Küpper and others added 2 commits October 7, 2026 05:48
The copying nursery guard starts with no root scanners. These tests call
Object.setPrototypeOf and Object.getPrototypeOf on builtin owners, which
build intrinsics inside the window and mint key atoms in the string atom
table. A copying minor then freed those atoms while the table still named
them. The next intrinsic build used a freed address as a key, and a key
list read a garbage length past the end of its 2 MiB block (#12137).

Register the atom and intern table, shape table and canonical keys
scanners, as production does.
@coderabbitai

coderabbitai Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Commit to this branch
  • Create a new PR
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@proggeramlug
proggeramlug merged commit 75c38e9 into main Oct 7, 2026
28 of 35 checks passed
@proggeramlug
proggeramlug deleted the fix/12137 branch October 7, 2026 06:02
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.

debug: residual_prototype_relocation test intermittently segfaults at a 2 MiB block base in the full gc test sequence

1 participant