A good panic/reover/Goexit explaination should cover these following cases.
- The program exits normally.
package main
func main() {
defer func() {
recover() // recover "bye"
}()
panic("bye")
}
- The program exits normally. Panic 2 shadows panic 1, then shadows panic 0.
package main
import "fmt"
func main() {
defer func() {
fmt.Print(recover())
}()
defer func() {
defer panic(2)
func () {
panic(1)
}()
}()
panic(0)
}
- The program crashes for panicking.
package main
func main() {
defer func() {
defer func() {
recover() // no-op
}()
}()
defer func() {
func() {
recover() // no-op
}()
}()
func() {
defer func() {
recover() // no-op
}()
}()
func() {
defer recover() // no-op
}()
func() {
recover() // no-op
}()
recover() // no-op
defer recover() // no-op
panic("bye")
}
- The second
recover
call (by line number) is a no-op.
package main
func demo() {
defer func() {
defer func() {
recover() // this one recovers panic 2
}()
defer recover() // no-op
panic(2)
}()
panic(1)
}
func main() {
demo()
}
- The program should exit quickly.
package main
import "runtime"
func f() {
defer func() {
recover()
}()
defer panic("bye")
runtime.Goexit()
}
func main() {
c := make(chan struct{})
go func() {
defer close(c)
f()
for {
runtime.Gosched()
}
}()
<-c
}
- The program should exit for panicking?
package main
import "runtime"
func main() {
c := make(chan struct{})
go func() {
defer close(c)
defer runtime.Goexit()
panic("bye")
}()
<-c
}
- The program should exit normally?
package main
import (
"fmt"
"runtime"
)
func main() {
defer func() {
fmt.Print(recover())
}()
defer runtime.Goexit()
panic(0)
}