panic可能原因
1. 空指针
2. 直接调用panic函数
3. 数组越界
4. map读写并发(recover不能恢复)
core dump
程序出现段错误时出现的错误文件,通过该文件确认错误的位置。
程序因段错误异常终止时打印堆栈信息
// 开启core dump功能,不限制core文件大小
ulimit -c unlimited
// 临时修改core文件保存位置
echo /var/log/%e.core.%p > /proc/sys/kernel/core_pattern
// 触发core dump
export GOTRACEBACK=crash
并发读写map示例代码
package main
import (
"fmt"
"time"
)
func main(){
c := make(map[string]int)
// 写map
go func() {
for j := 0; j < 1000000; j++ {
c[fmt.Sprintf("%d", j)] = j
}
}()
// 读map
go func() {
for j := 0; j < 1000000; j++ {
fmt.Println(c[fmt.Sprintf("%d",j)])
}
}()
time.Sleep(time.Second*20)
}
自动生成coredump文件
使用golang的dlv来调试core文件
git clone https://github.com/go-delve/delve
cd delve/cmd/dlv/
交叉编译dlv
GOOS=linux GOARCH=amd64 go build
拷贝到目标机器上后,--check-go-version=false 忽略go版本和dlv版本的区别
./dlv core {这里是你的程序} {这里是coredump文件} --check-go-version=false
bt
分析堆栈的错误
引入pprof
关闭防火墙服务,确保外部可以正常访问机器pprof
systemctl stop firewalld.service
import _ "net/http/pprof"
go func() {
http.ListenAndServe(":7000", nil)
}()
浏览器直接打开
http://localhost:7000/debug/pprof/