From 9fa153b729969855fcb694e12c16e20b1407ed9c Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Fri, 9 Feb 2024 13:49:21 -0500 Subject: [PATCH] runtime: don't call traceReadCPU on the system stack traceReadCPU calls profBuf.read, which does a raceacquire. g0 does not have a race context, so this crashes when running on the system stack. We could borrow a race context, but it is simpler to just move traceReadCPU off of the system stack. Fixes #65607. Change-Id: I335155b96d683aebb92b2f4e1eea063dd139f2d5 Reviewed-on: https://go-review.googlesource.com/c/go/+/562996 Auto-Submit: Michael Pratt LUCI-TryBot-Result: Go LUCI Reviewed-by: Michael Knyszek --- src/runtime/trace2.go | 3 +++ src/runtime/trace2cpu.go | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/runtime/trace2.go b/src/runtime/trace2.go index d40596f39be985..673205dda8a4a6 100644 --- a/src/runtime/trace2.go +++ b/src/runtime/trace2.go @@ -516,6 +516,9 @@ func traceAdvance(stopTrace bool) { } statusWriter.flush().end() + // Read everything out of the last gen's CPU profile buffer. + traceReadCPU(gen) + systemstack(func() { // Flush CPU samples, stacks, and strings for the last generation. This is safe, // because we're now certain no M is writing to the last generation. diff --git a/src/runtime/trace2cpu.go b/src/runtime/trace2cpu.go index 95c62c44b44114..4635662c08d56a 100644 --- a/src/runtime/trace2cpu.go +++ b/src/runtime/trace2cpu.go @@ -112,6 +112,9 @@ func traceStopReadCPU() { // // No more than one goroutine may be in traceReadCPU for the same // profBuf at a time. +// +// Must not run on the system stack because profBuf.read performs race +// operations. func traceReadCPU(gen uintptr) bool { var pcBuf [traceStackSize]uintptr @@ -198,9 +201,6 @@ func traceReadCPU(gen uintptr) bool { // //go:systemstack func traceCPUFlush(gen uintptr) { - // Read everything out of the last gen's CPU profile buffer. - traceReadCPU(gen) - // Flush any remaining trace buffers containing CPU samples. if buf := trace.cpuBuf[gen%2]; buf != nil { lock(&trace.lock)