aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/panic.go
diff options
context:
space:
mode:
authorDamien Neil <dneil@google.com>2025-02-21 10:55:32 -0800
committerGopher Robot <gobot@golang.org>2025-05-07 11:43:43 -0700
commit86101b083ad14bb0c6ca9c55d2869cba57760046 (patch)
treef4cb84ed0de02c1005004a01a264fcc9b8f732ce /src/runtime/panic.go
parentab2a92dd84aa4d0e12e7a6ef929aee765dd2aa8d (diff)
downloadgo-86101b083ad14bb0c6ca9c55d2869cba57760046.tar.xz
runtime: print stack traces for bubbled goroutines on synctest deadlock
When synctest.Run panics due to every goroutine in the bubble being blocked, print a stack trace for every goroutine in the bubble. For #67434 Change-Id: Ie751c2ee6fa136930b18f4bee0277ff30da46905 Reviewed-on: https://go-review.googlesource.com/c/go/+/645719 Auto-Submit: Damien Neil <dneil@google.com> Reviewed-by: Michael Pratt <mpratt@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src/runtime/panic.go')
-rw-r--r--src/runtime/panic.go29
1 files changed, 23 insertions, 6 deletions
diff --git a/src/runtime/panic.go b/src/runtime/panic.go
index 281fe04bca..706f9879dc 100644
--- a/src/runtime/panic.go
+++ b/src/runtime/panic.go
@@ -1272,7 +1272,7 @@ func fatalthrow(t throwType) {
startpanic_m()
- if dopanic_m(gp, pc, sp) {
+ if dopanic_m(gp, pc, sp, nil) {
// crash uses a decent amount of nosplit stack and we're already
// low on stack in throw, so crash on the system stack (unlike
// fatalpanic).
@@ -1310,7 +1310,14 @@ func fatalpanic(msgs *_panic) {
printpanics(msgs)
}
- docrash = dopanic_m(gp, pc, sp)
+ // If this panic is the result of a synctest bubble deadlock,
+ // print stacks for the goroutines in the bubble.
+ var sg *synctestGroup
+ if de, ok := msgs.arg.(synctestDeadlockError); ok {
+ sg = de.sg
+ }
+
+ docrash = dopanic_m(gp, pc, sp, sg)
})
if docrash {
@@ -1392,7 +1399,8 @@ var deadlock mutex
// gp is the crashing g running on this M, but may be a user G, while getg() is
// always g0.
-func dopanic_m(gp *g, pc, sp uintptr) bool {
+// If sg is non-nil, print the stacks for goroutines in this group as well.
+func dopanic_m(gp *g, pc, sp uintptr, sg *synctestGroup) bool {
if gp.sig != 0 {
signame := signame(gp.sig)
if signame != "" {
@@ -1416,10 +1424,19 @@ func dopanic_m(gp *g, pc, sp uintptr) bool {
print("\nruntime stack:\n")
traceback(pc, sp, 0, gp)
}
- if !didothers && all {
- didothers = true
- tracebackothers(gp)
+ if !didothers {
+ if all {
+ didothers = true
+ tracebackothers(gp)
+ } else if sg != nil {
+ // This panic is caused by a synctest bubble deadlock.
+ // Print stacks for goroutines in the deadlocked bubble.
+ tracebacksomeothers(gp, func(other *g) bool {
+ return sg == other.syncGroup
+ })
+ }
}
+
}
unlock(&paniclk)