SYSTEM Cited by 1 source
Go runtime scheduler¶
The Go runtime scheduler is the userspace
M:N scheduler that multiplexes a
large number of goroutines onto a smaller number of OS kernel
threads. Documented in src/runtime/HACKING.md.
The three core types¶
| Type | Role | Field of note |
|---|---|---|
g |
Goroutine | m — pointer to the kernel thread currently running it (nil if not scheduled) |
m |
Kernel thread ("machine") | incgo at offset 0x118 (fault address in the Cloudflare 2025-10 bug) |
p |
Physical execution context ("processor") | Queue of runnable gs; bound to an m when executing |
For a goroutine to execute: a free m acquires a free p,
which then executes a g. Each g records which m is
running it via the g.m back-pointer (nil if not currently
scheduled).
sysmon and async preemption¶
The runtime spawns a dedicated monitoring thread, sysmon,
that scans running goroutines and preempts any that have run
longer than 10 ms (at time of writing). Preemption is
performed by sending SIGURG to the goroutine's m; the
signal handler mutates the program counter + stack to
synthesise a call to runtime.asyncPreempt. See
concepts/async-preemption-go.
Before Go 1.14, scheduling was cooperative — goroutines
yielded only at explicit points (runtime.Gosched(), function
prologues, I/O). Async preemption widens the instant-of-yield
from "call site" to "any instruction boundary".
Stack unwinding requires sp validity¶
The scheduler / GC / panic-recovery paths traverse goroutine
stacks via (*unwinder).next. The unwinder
dereferences sp to find the parent frame. If
sp is partially modified (mid-function-epilogue on arm64 with
a split-ADD stack adjustment), the unwinder reads garbage as
a return address. Two failure modes:
- Return address is null →
finishInternalthrowsfatal error: traceback did not unwind completely(traceback.go#L566). - Return address is non-zero but not a function → unwinder
assumes goroutine is running and
dereferences
m.incgoat offset0x118→ SIGSEGV.
Canonical wiki instance: the Cloudflare arm64 compiler bug.
Seen in¶
- sources/2025-10-08-cloudflare-we-found-a-bug-in-gos-arm64-compiler
— scheduler structs + async preemption + stack unwinding
are all load-bearing context for the crash shape; the
specific fault is
m.incgoat offset0x118.
Related¶
- concepts/m-n-scheduler — the general scheduling model.
- concepts/async-preemption-go — the preemption mechanism.
- concepts/stack-unwinding — scheduler/GC/panic paths that
read
spand require it to be valid. - systems/go-compiler — emits the code whose SP-adjustment must be preemption-safe.