From 7e952962dff6aafb9ed888a86a7208f01fbe9508 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Wed, 20 Jul 2022 11:09:14 -0400 Subject: runtime: clean up canpanic * The gp argument to canpanic is always equivalent to getg(), so no need to pass it at all. * gp must not be nil or _g_.m would have crashed, so no need to check for nil. * Use acquirem to better reason about preemption. Change-Id: Ic7dc8dc1e56ab4c1644965f6aeba16807cdb2df4 Reviewed-on: https://go-review.googlesource.com/c/go/+/418575 Reviewed-by: Austin Clements TryBot-Result: Gopher Robot Run-TryBot: Michael Pratt --- src/runtime/panic.go | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'src/runtime/panic.go') diff --git a/src/runtime/panic.go b/src/runtime/panic.go index 121f2022a4..ab8d1f82b4 100644 --- a/src/runtime/panic.go +++ b/src/runtime/panic.go @@ -1290,29 +1290,32 @@ func dopanic_m(gp *g, pc, sp uintptr) bool { // panicking. // //go:nosplit -func canpanic(gp *g) bool { - // Note that g is m->gsignal, different from gp. - // Note also that g->m can change at preemption, so m can go stale - // if this function ever makes a function call. - _g_ := getg() - mp := _g_.m +func canpanic() bool { + gp := getg() + mp := acquirem() // Is it okay for gp to panic instead of crashing the program? // Yes, as long as it is running Go code, not runtime code, // and not stuck in a system call. - if gp == nil || gp != mp.curg { + if gp != mp.curg { + releasem(mp) return false } - if mp.locks != 0 || mp.mallocing != 0 || mp.throwing != throwTypeNone || mp.preemptoff != "" || mp.dying != 0 { + // N.B. mp.locks != 1 instead of 0 to account for acquirem. + if mp.locks != 1 || mp.mallocing != 0 || mp.throwing != throwTypeNone || mp.preemptoff != "" || mp.dying != 0 { + releasem(mp) return false } status := readgstatus(gp) if status&^_Gscan != _Grunning || gp.syscallsp != 0 { + releasem(mp) return false } if GOOS == "windows" && mp.libcallsp != 0 { + releasem(mp) return false } + releasem(mp) return true } -- cgit v1.3-5-g9baa