底层逻辑
goroutine_panicpanic_panicdefer_panicpanicpanic_panic结构体
go_panictype _panic struct {
argp unsafe.Pointer // pointer to arguments of deferred call run during panic; cannot move - known to liblink
arg interface{} // argument to panic
link *_panic // link to earlier panic
pc uintptr // where to return to in runtime if this panic is bypassed
sp unsafe.Pointer // where to return to in runtime if this panic is bypassed
recovered bool // whether this panic is over
aborted bool // the panic was aborted
goexit bool
}pcspgoexitruntime.Goexitruntime.Goexitdeferpanicrecover嵌套panic
接下来用个嵌套的panic例子来强化理解一下上面讲的
package main
func main() {
defer func() {
defer func() {
panic("双重嵌套:panic")
}()
panic("panic1")
}()
defer func() {
panic("panic2")
}()
panic("main-panic")
}输出:
panic: main-panic
panic: panic2
panic: panic1
panic: 双重嵌套:panic
goroutine 1 [running]:
main.main.func1.1()
/home/zheng/STUDY/GoWork/demo/main.go:6 +0x39
panic(0x466460, 0x48a2b8)
/usr/local/go/src/runtime/panic.go:965 +0x1b9
main.main.func1()
/home/zheng/STUDY/GoWork/demo/main.go:8 +0x5b
panic(0x466460, 0x48a2c8)
/usr/local/go/src/runtime/panic.go:965 +0x1b9
main.main.func2()
/home/zheng/STUDY/GoWork/demo/main.go:11 +0x39
panic(0x466460, 0x48a298)
/usr/local/go/src/runtime/panic.go:965 +0x1b9
main.main()
/home/zheng/STUDY/GoWork/demo/main.go:13 +0x68图解:
recovery
_panicrecoveredtruepanicpanicruntime.gorecoverfunc gorecover(argp uintptr) interface{} {
gp := getg()
p := gp._panic
if p != nil && !p.recovered && argp == uintptr(p.argp) {
p.recovered = true
return p.arg
}
return nil
}recoverydeferpanic