diff options
author | Michael Pratt <mpratt@google.com> | 2024-02-09 13:49:21 -0500 |
---|---|---|
committer | Than McIntosh <thanm@google.com> | 2024-02-16 15:51:46 +0000 |
commit | 6fbd01a71108b185479457fd9393b78bcd3dde55 (patch) | |
tree | f1ec713f9ad128e219f964288e88f0a6a92e1148 | |
parent | d6a271939f3321aad5c3c5c3a9e34641c26400d3 (diff) | |
download | go-6fbd01a71108b185479457fd9393b78bcd3dde55.tar.gz go-6fbd01a71108b185479457fd9393b78bcd3dde55.zip |
[release-branch.go1.22] 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.
For #65607.
Fixes #65644.
Change-Id: I335155b96d683aebb92b2f4e1eea063dd139f2d5
Reviewed-on: https://go-review.googlesource.com/c/go/+/562996
Auto-Submit: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
(cherry picked from commit 9fa153b729969855fcb694e12c16e20b1407ed9c)
Reviewed-on: https://go-review.googlesource.com/c/go/+/562559
-rw-r--r-- | src/runtime/trace2.go | 3 | ||||
-rw-r--r-- | 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 d40596f39b..673205dda8 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 95c62c44b4..4635662c08 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) |