not all panics can be recovered, such as map concurrent panic can not be recovered using defer-recover mechanism.
package main
import (
"fmt"
"strconv"
"time"
)
func main() {
m := map[string]int{
"k1": 1,
"k2": 2,
}
go func() {
defer func() {
if e := recover(); e != nil {
fmt.Println("1", e)
}
}()
for i := 3; i < 20; i++ {
m["k"+strconv.Itoa(i)] = i
}
}()
go func() {
defer func() {
if e := recover(); e != nil {
fmt.Println("2", e)
}
}()
for i := 3; i < 20; i++ {
m["k"+strconv.Itoa(i)] = i
}
}()
time.Sleep(1 * time.Second)
}
and also note that the code above will not panic 100%, relying on if the two goroutines are scheduling at the same time or scheduling sequentially. so the output may like:
wangfeng@wangfengdeMacBook-Pro goproject % go run src/main.go
wangfeng@wangfengdeMacBook-Pro goproject % go run src/main.go
wangfeng@wangfengdeMacBook-Pro goproject % go run src/main.go
wangfeng@wangfengdeMacBook-Pro goproject % go run src/main.go
wangfeng@wangfengdeMacBook-Pro goproject % go run src/main.go
fatal error: concurrent map writes
goroutine 19 [running]:
runtime.throw({0x100e538a1?, 0x0?})
/usr/local/go/src/runtime/panic.go:992 +0x50 fp=0x14000049700 sp=0x140000496d0 pc=0x100df6b90