aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Pratt <mpratt@google.com>2024-02-09 13:49:21 -0500
committerThan McIntosh <thanm@google.com>2024-02-16 15:51:46 +0000
commit6fbd01a71108b185479457fd9393b78bcd3dde55 (patch)
treef1ec713f9ad128e219f964288e88f0a6a92e1148
parentd6a271939f3321aad5c3c5c3a9e34641c26400d3 (diff)
downloadgo-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.go3
-rw-r--r--src/runtime/trace2cpu.go6
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)