golang coredump
golang生成coredump文件
refer:
https://blog.csdn.net/xmcy001122/article/details/105665732
http://t.zoukankan.com/lit10050528-p-4811833.html
1.设置coredump文件
1).临时设置
echo "/tmp/core-%e-%p-%s-%t" > /proc/sys/kernel/core_pattern
echo 1 > /proc/sys/kernel/core_pid
2).永久设置
echo -e "\nkernel.core_pattern=/tmp/core-%e-%p-%s-%t" >> /etc/sysctl.conf
echo -e "\nkernel.core_uses_pid = 1" >> /etc/sysctl.conf
sysctl -p /etc/sysctl.conf
2.设置环境变量
echo "GOTRACEBACK=crash" >> ~/.bashrc
3.执行程序
go build -o meng.out meng.go
./meng.out
或者2,3步骤合并:
GOTRACEBACK=crash ./meng.out
4.调试coredump
gdb ./meng.out /tmp/core-meng-399155-6-1669296379
或
dlv ./meng.out /tmp/core-meng-399155-6-1669296379
>>
>>bt
0 0x000000000045cf41 in runtime.raise
at /usr/local/src/go/src/runtime/sys_linux_amd64.s:165
1 0x0000000000443a25 in runtime.dieFromSignal
at /usr/local/src/go/src/runtime/signal_unix.go:769
。。。。。。
10 0x000000000048ae1f in main.doCommitTask.func1
at ./meng.go:27
>>frame 10(报错所在栈)
>>list
5.附:meng.go
refer:
https://blog.csdn.net/xmcy001122/article/details/105665732
http://t.zoukankan.com/lit10050528-p-4811833.html
1.设置coredump文件
1).临时设置
echo "/tmp/core-%e-%p-%s-%t" > /proc/sys/kernel/core_pattern
echo 1 > /proc/sys/kernel/core_pid
2).永久设置
echo -e "\nkernel.core_pattern=/tmp/core-%e-%p-%s-%t" >> /etc/sysctl.conf
echo -e "\nkernel.core_uses_pid = 1" >> /etc/sysctl.conf
sysctl -p /etc/sysctl.conf
2.设置环境变量
echo "GOTRACEBACK=crash" >> ~/.bashrc
3.执行程序
go build -o meng.out meng.go
./meng.out
或者2,3步骤合并:
GOTRACEBACK=crash ./meng.out
4.调试coredump
gdb ./meng.out /tmp/core-meng-399155-6-1669296379
或
dlv ./meng.out /tmp/core-meng-399155-6-1669296379
>>
>>bt
0 0x000000000045cf41 in runtime.raise
at /usr/local/src/go/src/runtime/sys_linux_amd64.s:165
1 0x0000000000443a25 in runtime.dieFromSignal
at /usr/local/src/go/src/runtime/signal_unix.go:769
。。。。。。
10 0x000000000048ae1f in main.doCommitTask.func1
at ./meng.go:27
>>frame 10(报错所在栈)
>>list
5.附:meng.go
1 package main 2 3 import ( 4 "errors" 5 "fmt" 6 7 "time" 8 "runtime" 9 "path" 10 ) 11 12 func main() { 13 fmt.Printf("Hello world!\n") 14 taskIds := make([]int32, 0) 15 go doCommitTask(&taskIds) 16 time.Sleep(10*time.Second) 17 fmt.Printf("taskIds=%v\n", taskIds) 18 } 19 20 func doCommitTask(taskIds *[]int32) { 21 defer func() { 22 err := recover() 23 if err != nil { 24 fmt.Printf("error: err=%v\n", err) 25 } 26 fmt.Printf("defer: now=%v\n", time.Now()) 27 panic("now") 28 }() 29 fmt.Printf("doCommitTask: start2\n") 30 panic("jack at home2") 31 for i := int32(0); i < 100; i += 1 { 32 *taskIds = append(*taskIds, i) 33 } 34 } 35 36 37 func play() { 38 defer func() { 39 if err := recover(); err != nil { 40 fmt.Errorf("panic in safeGo: %v", err) 41 } 42 }() 43 fmt.Printf("player: hello\n") 44 err := errors.New("player stop") 45 panic(err) 46 fmt.Printf("player: world\n\n") 47 } 48 49 func SafeGo(fun func()) { 50 defer func() { 51 if err := recover(); err != nil { 52 fmt.Errorf("panic in safeGo: %v", err) 53 } 54 }() 55 fun() 56 } 57 58 func getRootPath(skip int) string { 59 pc, fileName, line, ok := runtime.Caller(skip) 60 if !ok { 61 fmt.Printf("StartUp: runtime.Caller is error.\n") 62 return "" 63 } 64 funcName := runtime.FuncForPC(pc).Name() 65 rootPath := path.Dir(fileName) 66 fmt.Printf("getRootPath: skip=%d, funcName=%s, rootPath=%s, fileName=%s, line=%d.\n", skip, funcName, rootPath, fileName, line) 67 GetNextZeroTime() 68 return rootPath 69 } 70 71 //当地时间下一次0点 72 func GetNextZeroTime() int64 { 73 nowTime := time.Now() 74 now := nowTime.Unix() 75 _, offsetSeconds := nowTime.Zone() //相对于utc时区偏移秒数 76 sec := (now + int64(offsetSeconds)) % 86400 //相对于当前时区0点偏移秒数 77 return now - sec + 86400 78 } 79 80 func PrintLatestStack(playerId int32, skip int) { 81 fmt.Printf("PrintLatestStack: playerId=%d, traces:\n", playerId) 82 pcs := make([]uintptr, 10) 83 n := runtime.Callers(skip+2, pcs) 84 for i := 0; i < n; i += 1 { 85 pc := pcs[i] 86 runFunc := runtime.FuncForPC(pc) 87 fileName, line := runFunc.FileLine(pc) 88 fmt.Printf("funcName=%s, fileName=%s, line=%d.\n", runFunc.Name(), fileName, line) 89 } 90 }