mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: iterate through inlinings when processing recover()
We care about the wrapper-ness of logical frames, not physical frames. Fixes #73916 Fixes #73917 Fixex #73920 Change-Id: Ia17c8390e71e6c0e13e23dcbb7bc7273ef25da90 Reviewed-on: https://go-review.googlesource.com/c/go/+/685375 Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Cherry Mui <cherryyz@google.com>
This commit is contained in:
parent
c76c3abc54
commit
08376e1a9c
5 changed files with 160 additions and 11 deletions
|
|
@ -1142,18 +1142,21 @@ func gorecover(_ uintptr) any {
|
||||||
nonWrapperFrames := 0
|
nonWrapperFrames := 0
|
||||||
loop:
|
loop:
|
||||||
for ; u.valid(); u.next() {
|
for ; u.valid(); u.next() {
|
||||||
switch u.frame.fn.funcID {
|
for iu, f := newInlineUnwinder(u.frame.fn, u.symPC()); f.valid(); f = iu.next(f) {
|
||||||
case abi.FuncIDWrapper:
|
sf := iu.srcFunc(f)
|
||||||
continue
|
switch sf.funcID {
|
||||||
case abi.FuncID_gopanic:
|
case abi.FuncIDWrapper:
|
||||||
if u.frame.fp == uintptr(p.gopanicFP) && nonWrapperFrames > 0 {
|
continue
|
||||||
canRecover = true
|
case abi.FuncID_gopanic:
|
||||||
}
|
if u.frame.fp == uintptr(p.gopanicFP) && nonWrapperFrames > 0 {
|
||||||
break loop
|
canRecover = true
|
||||||
default:
|
}
|
||||||
nonWrapperFrames++
|
|
||||||
if nonWrapperFrames > 1 {
|
|
||||||
break loop
|
break loop
|
||||||
|
default:
|
||||||
|
nonWrapperFrames++
|
||||||
|
if nonWrapperFrames > 1 {
|
||||||
|
break loop
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
32
test/fixedbugs/issue73916.go
Normal file
32
test/fixedbugs/issue73916.go
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
// run
|
||||||
|
|
||||||
|
// 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 main
|
||||||
|
|
||||||
|
func callRecover() {
|
||||||
|
if recover() != nil {
|
||||||
|
println("recovered")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func F(int) { callRecover() }
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
mustPanic(func() {
|
||||||
|
defer F(1)
|
||||||
|
panic("XXX")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustPanic(f func()) {
|
||||||
|
defer func() {
|
||||||
|
r := recover()
|
||||||
|
if r == nil {
|
||||||
|
panic("didn't panic")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
f()
|
||||||
|
}
|
||||||
34
test/fixedbugs/issue73916b.go
Normal file
34
test/fixedbugs/issue73916b.go
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
// run
|
||||||
|
|
||||||
|
// 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 main
|
||||||
|
|
||||||
|
func callRecover() {
|
||||||
|
func() {
|
||||||
|
if recover() != nil {
|
||||||
|
println("recovered")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
func F() int { callRecover(); return 0 }
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
mustPanic(func() {
|
||||||
|
defer F()
|
||||||
|
panic("XXX")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustPanic(f func()) {
|
||||||
|
defer func() {
|
||||||
|
r := recover()
|
||||||
|
if r == nil {
|
||||||
|
panic("didn't panic")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
f()
|
||||||
|
}
|
||||||
40
test/fixedbugs/issue73917.go
Normal file
40
test/fixedbugs/issue73917.go
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
// run
|
||||||
|
|
||||||
|
// 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 main
|
||||||
|
|
||||||
|
func callRecover() {
|
||||||
|
if recover() != nil {
|
||||||
|
println("recovered")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type T int
|
||||||
|
|
||||||
|
func (*T) M() { callRecover() }
|
||||||
|
|
||||||
|
type S struct{ *T } // has a wrapper S.M wrapping (*T.M)
|
||||||
|
|
||||||
|
var p = S{new(T)}
|
||||||
|
|
||||||
|
var fn = S.M // using a function pointer to force using the wrapper
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
mustPanic(func() {
|
||||||
|
defer fn(p)
|
||||||
|
panic("XXX")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustPanic(f func()) {
|
||||||
|
defer func() {
|
||||||
|
r := recover()
|
||||||
|
if r == nil {
|
||||||
|
panic("didn't panic")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
f()
|
||||||
|
}
|
||||||
40
test/fixedbugs/issue73920.go
Normal file
40
test/fixedbugs/issue73920.go
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
// run
|
||||||
|
|
||||||
|
// 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 main
|
||||||
|
|
||||||
|
func callRecover() {
|
||||||
|
if recover() != nil {
|
||||||
|
println("recovered")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type T int
|
||||||
|
|
||||||
|
func (*T) M() { callRecover() }
|
||||||
|
|
||||||
|
type S struct{ *T } // has a wrapper (*S).M wrapping (*T.M)
|
||||||
|
|
||||||
|
var p = &S{new(T)}
|
||||||
|
|
||||||
|
var fn = (*S).M // using a function pointer to force using the wrapper
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
mustPanic(func() {
|
||||||
|
defer fn(p)
|
||||||
|
panic("XXX")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustPanic(f func()) {
|
||||||
|
defer func() {
|
||||||
|
r := recover()
|
||||||
|
if r == nil {
|
||||||
|
panic("didn't panic")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
f()
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue