Follow-up to yesterday's gVisor intro . This is the stub-memory bug I mentioned there, with the debugging steps.
gVisor's systrap platform runs app code in host "stub" processes and shifts their shared memory by a random, page-aligned gap at startup, so the addresses are hard to guess. In stub_unsafe.go three regions get += gap . The spinning queue, sitting between them in the layout, did not.
With a big gap the queue sits alone in empty space. With a small one, the shifted per-thread stacks land on the queue's old address. The stub then spins in spinning_queue_remove_first waiting for a timestamp slot that stack bytes keep at 0. That check sits before the timeout, so it never gives up. The Sentry waits on a context no stub ever acknowledged, and my 30s fail-stop, which kills a stuck stub process, only arms once an acknowledged context was interrupted.…