Hi all,
In the following case, recover() cannot recover a panic.
playground: https://go.dev/play/p/cPkUZb6mbmt
package main
import "fmt"
func main() {
d := div(1, 0)
fmt.Println("Returned from div(): ", d)
}
func div(a, b int64) int64 {
defer recover()
if b == 0 {
panic("integer divide by zero")
}
return a/b
}
The gorecover() function (below) checks whether argp is equal to p.argp, if they match, the caller is the one who can recover.
func gorecover(argp uintptr) interface{} {
gp := getg()
p := gp._panic
if p != nil && !p.goexit && !p.recovered && argp == uintptr(p.argp) {
p.recovered = true
return p.arg
}
return nil
}
But for the above case, argp = div()’arpg = main()’sp +8, p.argp = gopanic()’argp = div()’sp + 8. They are not equal, causing gorecover to fail to recover and return nil.
Of course, I know the rationality and necessity of this check, but from my understanding of the above case, the recover in div deferred function should be able to recover the panic that occurred in the div?
What do you think?
If you think it should be able to recover, then in this case, the argp passed to gorecover should be recover()'argp, which is div()'sp+8.
Thanks & Best regards,
Fannie Zhang