Skip to content

runtime: fix conservative and precise GC freeing live objects - #5822

Draft
davecheney wants to merge 1 commit into
tinygo-org:devfrom
davecheney:davecheney-gc-missed-root-bug
Draft

davecheney wants to merge 1 commit into
tinygo-org:devfrom
davecheney:davecheney-gc-missed-root-bug

Conversation

@davecheney

@davecheney davecheney commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

The conservative and precise GCs can free objects that are still in use on bare-metal targets and native -scheduler=tasks builds. This is possibly exposed by commit c9aa88b ("runtime (gc_blocks.go): use a linked stack to scan marked objects").

A pointer held only in a callee-saved register when a collection runs is not marked, so the object it points to is freed. Seen on cortex-m-qemu at -opt=0 and -opt=z, riscv-qemu at -opt=0, and native -scheduler=tasks at -opt=0.

This change scans the current goroutine stack while those registers are still saved on it, which fixes the missed roots.

It adds a regression test, gc-register-root.go, and a runtime package test, and runs the runtime package tests in CI. gc-register-root.go is skipped on simavr, where runtime.GC does not return, and on riscv-qemu, where it can time out under load. Both are unrelated to this change.

The conservative and precise GCs can free objects that are still in
use on bare-metal targets and native -scheduler=tasks builds. This is
possibly exposed by commit c9aa88b ("runtime (gc_blocks.go): use a
linked stack to scan marked objects").

A pointer held only in a callee-saved register when a collection runs
is not marked, so the object it points to is freed. Seen on
cortex-m-qemu at -opt=0 and -opt=z, riscv-qemu at -opt=0, and native
-scheduler=tasks at -opt=0.

This change scans the current goroutine stack while those registers
are still saved on it, which fixes the missed roots.

It adds a regression test, gc-register-root.go, and a runtime package
test, and runs the runtime package tests in CI. gc-register-root.go is
skipped on simavr, where runtime.GC does not return, and on
riscv-qemu, where it can time out under load. Both are unrelated to
this change.
@davecheney
davecheney force-pushed the davecheney-gc-missed-root-bug branch from 5d5edbd to 54fe077 Compare October 3, 2026 04:15
@davecheney davecheney changed the title runtime: scan current goroutine stack before saved registers are popped runtime: fix conservative and precise GC freeing live objects Oct 3, 2026
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