aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
authorCherry Mui <cherryyz@google.com>2025-07-11 11:41:23 -0400
committerCherry Mui <cherryyz@google.com>2025-07-11 11:41:23 -0400
commit21596f2f756edd4a5d67f0bfedb435bc1b29c6b3 (patch)
treea6f8275bb38ef1680f1cc3671a4f0411fe4829cb /src/runtime
parentab7f839280df8734c388046f957f7f37ae5b0998 (diff)
parent88cf0c5d55a8c18da515485f4a3fcf008b96cb07 (diff)
downloadgo-21596f2f756edd4a5d67f0bfedb435bc1b29c6b3.tar.xz
[dev.simd] all: merge master (88cf0c5) into dev.simd
Merge List: + 2025-07-11 88cf0c5d55 cmd/link: do size fixups after symbol references are loaded + 2025-07-10 7a38975a48 os: trivial comment fix + 2025-07-10 aa5de9ebb5 synctest: fix comments for time.Now() in synctests + 2025-07-10 63ec70d4e1 crypto/cipher: Fix comment punctuation + 2025-07-09 8131635e5a runtime: run TestSignalDuringExec in its own process group + 2025-07-09 67c1704444 crypto/tls: empty server_name conf. ext. from server + 2025-07-08 54c9d77630 cmd/go: disable support for multiple vcs in one module + 2025-07-08 fca43a8436 internal: make struct comment match struct name + 2025-07-08 bb917bb030 cmd/compile: document that nosplit directive is unsafe + 2025-07-08 a5bda585d5 cmd/compile: run fmt on ssa + 2025-07-07 86b5ba7310 internal/trace: only test for sync preemption if async preemption is off + 2025-07-07 ef46e1b164 cmd/internal/doc: fix GOROOT skew and path joining bugs + 2025-07-07 75b43f9a97 runtime: make traceStack testable and add a benchmark + 2025-07-07 20978f46fd crypto/rsa: remove another forgotten note to future self + 2025-07-07 33fb4819f5 cmd/compile/internal/ssa: skip EndSequence entries in TestStmtLines + 2025-07-07 a995269a93 sort: clarify Less doc + 2025-07-03 6c3b5a2798 runtime: correct vdsoSP on S390X + 2025-07-03 dd687c3860 hash: document that Clone may only return ErrUnsupported or a nil error + 2025-07-02 b325151453 cmd/cgo/internal/testsanitizers: skip asan tests when FIPS140 mode is on + 2025-07-02 15d9fe43d6 testing/synctest: explicitly state Run will be removed in Go 1.26 + 2025-07-01 de646d94f7 cmd/go/internal/modindex: apply changes in CL 502615 to modindex package + 2025-07-01 2f653a5a9e crypto/tls: ensure the ECDSA curve matches the signature algorithm + 2025-07-01 6e95fd96cc crypto/ecdsa: fix crypto/x509 godoc links + 2025-07-01 7755a05209 Revert "crypto/internal/fips140/subtle: add assembly implementation of xorBytes for arm" + 2025-07-01 d168ad18e1 slices: update TestIssue68488 to avoid false positives + 2025-07-01 27ad1f5013 internal/abi: fix comment on NonEmptyInterface + 2025-06-30 86fca3dcb6 encoding/json/jsontext: use bytes.Buffer.AvailableBuffer + 2025-06-30 6bd9944c9a encoding/json/v2: avoid escaping jsonopts.Struct + 2025-06-30 e46d586edd cmd/compile/internal/escape: add debug hash for literal allocation optimizations + 2025-06-30 479b51ee1f cmd/compile/internal/escape: stop disabling literal allocation optimizations when coverage is enabled + 2025-06-30 8002d283e8 crypto/tls: update bogo version + 2025-06-30 fdd7713fe5 internal/goexperiment: fix godoc formatting Change-Id: I074e6c75778890930975925c016004aabca2b9d1
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/export_test.go10
-rw-r--r--src/runtime/metrics/doc.go5
-rw-r--r--src/runtime/runtime-gdb_test.go3
-rw-r--r--src/runtime/symtab.go5
-rw-r--r--src/runtime/sys_linux_s390x.s4
-rw-r--r--src/runtime/testdata/testprognet/signalexec.go43
-rw-r--r--src/runtime/trace.go2
-rw-r--r--src/runtime/traceevent.go2
-rw-r--r--src/runtime/tracestack.go8
-rw-r--r--src/runtime/tracestack_test.go46
10 files changed, 118 insertions, 10 deletions
diff --git a/src/runtime/export_test.go b/src/runtime/export_test.go
index b3bb5d2c58..81542deb59 100644
--- a/src/runtime/export_test.go
+++ b/src/runtime/export_test.go
@@ -1919,3 +1919,13 @@ const (
BubbleAssocCurrentBubble = bubbleAssocCurrentBubble
BubbleAssocOtherBubble = bubbleAssocOtherBubble
)
+
+type TraceStackTable traceStackTable
+
+func (t *TraceStackTable) Reset() {
+ t.tab.reset()
+}
+
+func TraceStack(gp *G, tab *TraceStackTable) {
+ traceStack(0, gp, (*traceStackTable)(tab))
+}
diff --git a/src/runtime/metrics/doc.go b/src/runtime/metrics/doc.go
index 32fc436e1a..a1902bc6d7 100644
--- a/src/runtime/metrics/doc.go
+++ b/src/runtime/metrics/doc.go
@@ -230,6 +230,11 @@ Below is the full list of supported metrics, ordered lexicographically.
/gc/stack/starting-size:bytes
The stack size of new goroutines.
+ /godebug/non-default-behavior/allowmultiplevcs:events
+ The number of non-default behaviors executed by the cmd/go
+ package due to a non-default GODEBUG=allowmultiplevcs=...
+ setting.
+
/godebug/non-default-behavior/asynctimerchan:events
The number of non-default behaviors executed by the time package
due to a non-default GODEBUG=asynctimerchan=... setting.
diff --git a/src/runtime/runtime-gdb_test.go b/src/runtime/runtime-gdb_test.go
index 19ad29c127..47c1fe5851 100644
--- a/src/runtime/runtime-gdb_test.go
+++ b/src/runtime/runtime-gdb_test.go
@@ -78,6 +78,9 @@ func checkGdbVersion(t *testing.T) {
if major < 10 {
t.Skipf("skipping: gdb version %d.%d too old", major, minor)
}
+ if major < 12 || (major == 12 && minor < 1) {
+ t.Logf("gdb version <12.1 is known to crash due to a SIGWINCH recieved in non-interactive mode; if you see a crash, some test may be sending SIGWINCH to the whole process group. See go.dev/issue/58932.")
+ }
t.Logf("gdb version %d.%d", major, minor)
}
diff --git a/src/runtime/symtab.go b/src/runtime/symtab.go
index 8c6ef2b4fc..866c46a83d 100644
--- a/src/runtime/symtab.go
+++ b/src/runtime/symtab.go
@@ -981,6 +981,9 @@ func pcvalue(f funcInfo, off uint32, targetpc uintptr, strict bool) (int32, uint
// matches the cached contents.
const debugCheckCache = false
+ // If true, skip checking the cache entirely.
+ const skipCache = false
+
if off == 0 {
return -1, 0
}
@@ -991,7 +994,7 @@ func pcvalue(f funcInfo, off uint32, targetpc uintptr, strict bool) (int32, uint
var checkVal int32
var checkPC uintptr
ck := pcvalueCacheKey(targetpc)
- {
+ if !skipCache {
mp := acquirem()
cache := &mp.pcvalueCache
// The cache can be used by the signal handler on this M. Avoid
diff --git a/src/runtime/sys_linux_s390x.s b/src/runtime/sys_linux_s390x.s
index 2f9d4beda8..a3472a4508 100644
--- a/src/runtime/sys_linux_s390x.s
+++ b/src/runtime/sys_linux_s390x.s
@@ -226,7 +226,7 @@ TEXT runtime·walltime(SB),NOSPLIT,$32-12
MOVD R4, 24(R15)
MOVD R14, R8 // Backup return address
- MOVD $sec+0(FP), R4 // return parameter caller
+ MOVD $ret-8(FP), R4 // caller's SP
MOVD R8, m_vdsoPC(R6)
MOVD R4, m_vdsoSP(R6)
@@ -312,7 +312,7 @@ TEXT runtime·nanotime1(SB),NOSPLIT,$32-8
MOVD R4, 24(R15)
MOVD R14, R8 // Backup return address
- MOVD $ret+0(FP), R4 // caller's SP
+ MOVD $ret-8(FP), R4 // caller's SP
MOVD R8, m_vdsoPC(R6)
MOVD R4, m_vdsoSP(R6)
diff --git a/src/runtime/testdata/testprognet/signalexec.go b/src/runtime/testdata/testprognet/signalexec.go
index 62ebce7176..7e7591e8f7 100644
--- a/src/runtime/testdata/testprognet/signalexec.go
+++ b/src/runtime/testdata/testprognet/signalexec.go
@@ -13,9 +13,11 @@ package main
import (
"fmt"
+ "io"
"os"
"os/exec"
"os/signal"
+ "runtime"
"sync"
"syscall"
"time"
@@ -23,10 +25,51 @@ import (
func init() {
register("SignalDuringExec", SignalDuringExec)
+ register("SignalDuringExecPgrp", SignalDuringExecPgrp)
register("Nop", Nop)
}
func SignalDuringExec() {
+ // Re-launch ourselves in a new process group.
+ cmd := exec.Command(os.Args[0], "SignalDuringExecPgrp")
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ cmd.SysProcAttr = &syscall.SysProcAttr{
+ Setpgid: true,
+ }
+
+ // Start the new process with an extra pipe. It will
+ // exit if the pipe is closed.
+ rp, wp, err := os.Pipe()
+ if err != nil {
+ fmt.Printf("Failed to create pipe: %v", err)
+ return
+ }
+ cmd.ExtraFiles = []*os.File{rp}
+
+ // Run the command.
+ if err := cmd.Run(); err != nil {
+ fmt.Printf("Run failed: %v", err)
+ }
+
+ // We don't actually need to write to the pipe, it just
+ // needs to get closed, which will happen on process
+ // exit.
+ runtime.KeepAlive(wp)
+}
+
+func SignalDuringExecPgrp() {
+ // Grab fd 3 which is a pipe we need to read on.
+ f := os.NewFile(3, "pipe")
+ go func() {
+ // Nothing will ever get written to the pipe, so we'll
+ // just block on it. If it closes, ReadAll will return
+ // one way or another, at which point we'll exit.
+ io.ReadAll(f)
+ os.Exit(1)
+ }()
+
+ // This is just for SignalDuringExec.
pgrp := syscall.Getpgrp()
const tries = 10
diff --git a/src/runtime/trace.go b/src/runtime/trace.go
index b92e7b4e8e..0d71ad445c 100644
--- a/src/runtime/trace.go
+++ b/src/runtime/trace.go
@@ -396,7 +396,7 @@ func traceAdvance(stopTrace bool) {
ug.status = readgstatus(s.g) &^ _Gscan
ug.waitreason = s.g.waitreason
ug.inMarkAssist = s.g.inMarkAssist
- ug.stackID = traceStack(0, gp, gen)
+ ug.stackID = traceStack(0, gp, &trace.stackTab[gen%2])
}
resumeG(s)
casgstatus(me, _Gwaiting, _Grunning)
diff --git a/src/runtime/traceevent.go b/src/runtime/traceevent.go
index 9d1a93d3f9..263847be2e 100644
--- a/src/runtime/traceevent.go
+++ b/src/runtime/traceevent.go
@@ -56,7 +56,7 @@ func (e traceEventWriter) event(ev tracev2.EventType, args ...traceArg) {
// It then returns a traceArg representing that stack which may be
// passed to write.
func (tl traceLocker) stack(skip int) traceArg {
- return traceArg(traceStack(skip, nil, tl.gen))
+ return traceArg(traceStack(skip, nil, &trace.stackTab[tl.gen%2]))
}
// startPC takes a start PC for a goroutine and produces a unique
diff --git a/src/runtime/tracestack.go b/src/runtime/tracestack.go
index 2ee68c85f0..76d6b05048 100644
--- a/src/runtime/tracestack.go
+++ b/src/runtime/tracestack.go
@@ -28,10 +28,8 @@ const (
// skip controls the number of leaf frames to omit in order to hide tracer internals
// from stack traces, see CL 5523.
//
-// Avoid calling this function directly. gen needs to be the current generation
-// that this stack trace is being written out for, which needs to be synchronized with
-// generations moving forward. Prefer traceEventWriter.stack.
-func traceStack(skip int, gp *g, gen uintptr) uint64 {
+// Avoid calling this function directly. Prefer traceEventWriter.stack.
+func traceStack(skip int, gp *g, tab *traceStackTable) uint64 {
var pcBuf [tracev2.MaxFramesPerStack]uintptr
// Figure out gp and mp for the backtrace.
@@ -134,7 +132,7 @@ func traceStack(skip int, gp *g, gen uintptr) uint64 {
if nstk > 0 && gp.goid == 1 {
nstk-- // skip runtime.main
}
- id := trace.stackTab[gen%2].put(pcBuf[:nstk])
+ id := tab.put(pcBuf[:nstk])
return id
}
diff --git a/src/runtime/tracestack_test.go b/src/runtime/tracestack_test.go
new file mode 100644
index 0000000000..eaf4d906e3
--- /dev/null
+++ b/src/runtime/tracestack_test.go
@@ -0,0 +1,46 @@
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime_test
+
+import (
+ "runtime"
+ "strconv"
+ "testing"
+)
+
+func BenchmarkTraceStack(b *testing.B) {
+ for _, stackDepth := range []int{1, 10, 100} {
+ b.Run("stackDepth="+strconv.Itoa(stackDepth), func(b *testing.B) {
+ benchmarkTraceStack(b, stackDepth)
+ })
+ }
+}
+
+func benchmarkTraceStack(b *testing.B, stackDepth int) {
+ var tab runtime.TraceStackTable
+ defer tab.Reset()
+
+ wait := make(chan struct{})
+ ready := make(chan struct{})
+ done := make(chan struct{})
+ var gp *runtime.G
+ go func() {
+ gp = runtime.Getg()
+ useStackAndCall(stackDepth, func() {
+ ready <- struct{}{}
+ <-wait
+ })
+ done <- struct{}{}
+ }()
+ <-ready
+
+ for b.Loop() {
+ runtime.TraceStack(gp, &tab)
+ }
+
+ // Clean up.
+ wait <- struct{}{}
+ <-done
+}