aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Chase <drchase@google.com>2023-08-11 14:38:19 -0400
committerGopher Robot <gobot@golang.org>2023-08-17 21:10:05 +0000
commitb4636682759ea7cd7a8ed480e4f98f401127306f (patch)
treeb96b581c830e65ab9a73c007db3cc65d26cf7985
parent974a3c9af7943a2c994d713c410bcadd7dca77b4 (diff)
downloadgo-b4636682759ea7cd7a8ed480e4f98f401127306f.tar.gz
go-b4636682759ea7cd7a8ed480e4f98f401127306f.zip
[release-branch.go1.20] runtime: profiling on Darwin cannot use blocking reads
On Darwin (and assume also on iOS but not sure), notetsleepg cannot be called in a signal-handling context. Avoid this by disabling block reads on Darwin. An alternate approach was to add "sigNote" with a pipe-based implementation on Darwin, but that ultimately would have required at least one more linkname between runtime and syscall to avoid racing with fork and opening the pipe, so, not. Fixes #62018. Updates #61768. Change-Id: I0e8dd4abf9a606a3ff73fc37c3bd75f55924e07e Reviewed-on: https://go-review.googlesource.com/c/go/+/518836 Run-TryBot: David Chase <drchase@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com> (cherry picked from commit c6ee8e31e3e7b01da54d241ae5a8eed350ab0e9f) Reviewed-on: https://go-review.googlesource.com/c/go/+/518677 Auto-Submit: Dmitri Shuralyov <dmitshur@google.com> Reviewed-by: Austin Clements <austin@google.com>
-rw-r--r--src/runtime/cpuprof.go6
-rw-r--r--src/runtime/os_darwin.go3
-rw-r--r--src/runtime/profbuf.go1
3 files changed, 8 insertions, 2 deletions
diff --git a/src/runtime/cpuprof.go b/src/runtime/cpuprof.go
index 6ef374eaa4..0d7eeacb39 100644
--- a/src/runtime/cpuprof.go
+++ b/src/runtime/cpuprof.go
@@ -227,7 +227,11 @@ func runtime_pprof_readProfile() ([]uint64, []unsafe.Pointer, bool) {
lock(&cpuprof.lock)
log := cpuprof.log
unlock(&cpuprof.lock)
- data, tags, eof := log.read(profBufBlocking)
+ readMode := profBufBlocking
+ if GOOS == "darwin" || GOOS == "ios" {
+ readMode = profBufNonBlocking // For #61768; on Darwin notes are not async-signal-safe. See sigNoteSetup in os_darwin.go.
+ }
+ data, tags, eof := log.read(readMode)
if len(data) == 0 && eof {
lock(&cpuprof.lock)
cpuprof.log = nil
diff --git a/src/runtime/os_darwin.go b/src/runtime/os_darwin.go
index c4f3bb6a81..105de47a1f 100644
--- a/src/runtime/os_darwin.go
+++ b/src/runtime/os_darwin.go
@@ -81,7 +81,7 @@ func semawakeup(mp *m) {
// The read and write file descriptors used by the sigNote functions.
var sigNoteRead, sigNoteWrite int32
-// sigNoteSetup initializes an async-signal-safe note.
+// sigNoteSetup initializes a single, there-can-only-be-one, async-signal-safe note.
//
// The current implementation of notes on Darwin is not async-signal-safe,
// because the functions pthread_mutex_lock, pthread_cond_signal, and
@@ -93,6 +93,7 @@ var sigNoteRead, sigNoteWrite int32
// not support timed waits but is async-signal-safe.
func sigNoteSetup(*note) {
if sigNoteRead != 0 || sigNoteWrite != 0 {
+ // Generalizing this would require avoiding the pipe-fork-closeonexec race, which entangles syscall.
throw("duplicate sigNoteSetup")
}
var errno int32
diff --git a/src/runtime/profbuf.go b/src/runtime/profbuf.go
index c579f21488..083b55a922 100644
--- a/src/runtime/profbuf.go
+++ b/src/runtime/profbuf.go
@@ -491,6 +491,7 @@ Read:
// Nothing to read right now.
// Return or sleep according to mode.
if mode == profBufNonBlocking {
+ // Necessary on Darwin, notetsleepg below does not work in signal handler, root cause of #61768.
return nil, nil, false
}
if !b.w.cas(bw, bw|profReaderSleeping) {