panic & recover
panic
// A _panic holds information about an active panic.
//
// A _panic value must only ever live on the stack.
//
// The argp and link fields are stack pointers, but don't need special
// handling during stack growth: because they are pointer-typed and
// _panic values only live on the stack, regular stack pointer
// adjustment takes care of them.
type _panic struct {
// defer 的参数空间地址
argp unsafe.Pointer // pointer to arguments of deferred call run during panic; cannot move - known to liblink
// panic 的参数
arg any // 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
}
recover
recover 只做一件事,把当前执行的 panic 置为已恢复,即把 recovered 字段值置为 true,移除并跳出当前 panic。
fucn A() {
defer A1()
defer A2()
// ......
panic("panicA")
// ......
}
func A2() {
p := recover()
fmt.Println(p)
}
recover 后会保存_defer.sp、_defer.pc。 sp 和 pc 是注册 defer 函数时保存的
func A() {
r = runtime.deferproc(0, A1)
if r > 0 {
goto ret
}
r = runtime.deferproc(0, A2)
if r > 0 {
goto ret
}
// code to do something
ret:
runtime.deferreturn()
}
sp 是函数 A 的栈指针 pc 是调用 deferproc 函数的返回地址
最后更新于