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
// 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
// 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
// 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) {