coredump是什么意思_core dump文件分析

大家好,我是知秋君,一个会写博客吟诗的知秋码农。今天说一说coredump是什么意思_core dump文件分析,希望能够帮助大家进步!!! 文章目录 dlv调试工具安装 调试Go程序core dump文件 Linux环境配置 Go环境配置 测试用例 总结 dlv调试工具安装 Github地址:https://github.com/go-delve/delve Linux安装: 参考地址

大家好,我是知秋君,一个会写博客吟诗的知秋码农。今天说一说coredump是什么意思_core dump文件分析,希望能够帮助大家进步!!!

dlv调试工具安装

Github地址:https://github.com/go-delve/delve

Linux安装:

参考地址:https://github.com/go-delve/delve/blob/master/Documentation/installation/linux/install.md

安装步骤(安装前确保$GOPATH已经安装):

$ git clone https://github.com/go-delve/delve.git $GOPATH/src/github.com/go-delve/delve $ cd $GOPATH/src/github.com/go-delve/delve $ make install 
只听到从知秋君办公室传来知秋君的声音:

乳燕飞华屋。有谁来对上联或下联?

调试Go程序core dump文件

默认Go程序是不会产生core dump文件的,需要一些配置才能产生。

Linux环境配置

ulimit -a:用来显示当前的各种用户进程限制。

此代码由一叶知秋网-知秋君整理
[root@localhost dlv-test]# ulimit -a core file size (blocks, -c) unlimited data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 7695 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 7695 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited

可以看到core file size (blocks, -c) 0产生core文件限制是0,就是不能产生core文件,所以需要将这个限制修改:ulimit -c unlimited

Go环境配置

要想让Go程序能产生core dump文件,需要配置GOTRACEBACK环境变量:

export GOTRACEBACK=crash或者在执行程序时指定(测试用例会演示)。

测试用例

// test.go package main import ( "fmt" "time" "unsafe" ) func main() { 

for i := 1;i <= 10;i++ {

go func(gid int) {

n := 0 for {

fmt.Println(time.Now().Format("2006-01-02 15:04:05"),gid,n) time.Sleep(time.Second) } }(i) } go func() {

arr := 0 p := uintptr(unsafe.Pointer(&arr)) myfun1(p) }() for true {

time.Sleep(time.Second) } } func myfun1(p uintptr) {

arr := (*int)(unsafe.Pointer(p)) *arr = 1 fmt.Println(*arr) go myfun2() fmt.Println(*arr) } func myfun2() {

fmt.Println("myfun2") myfun3() } func myfun3() {

var p uintptr = 0 arr := (*int)(unsafe.Pointer(p)) *arr = 1 fmt.Println(*arr) }

运行程序:

  1. go build test.go

  2. GOTRACEBACK=crash ./test

  3. 产生core.5121文件,使用dlv工具进行类gdb调试,命令dlv core test core.5121

启动dlv调试:

此代码由一叶知秋网-知秋君整理
[root@localhost dlv-test]# dlv core test core.5121 Type 'help' for list of commands. (dlv) goroutines Goroutine 1 - User: /usr/local/go/src/runtime/proc.go:310 time.Sleep (0x4448d7) Goroutine 2 - User: /usr/local/go/src/runtime/proc.go:305 runtime.gopark (0x42b7a0) Goroutine 3 - User: /usr/local/go/src/runtime/proc.go:305 runtime.gopark (0x42b7a0) Goroutine 4 - User: /usr/local/go/src/runtime/proc.go:305 runtime.gopark (0x42b7a0) Goroutine 5 - User: /usr/local/go/src/runtime/proc.go:305 runtime.gopark (0x42b7a0) Goroutine 6 - User: /usr/local/go/src/runtime/proc.go:310 time.Sleep (0x4448d7) Goroutine 7 - User: /usr/local/go/src/runtime/proc.go:310 time.Sleep (0x4448d7) Goroutine 8 - User: /usr/local/go/src/runtime/proc.go:310 time.Sleep (0x4448d7) Goroutine 9 - User: /usr/local/go/src/runtime/proc.go:310 time.Sleep (0x4448d7) Goroutine 10 - User: /usr/local/go/src/runtime/proc.go:310 time.Sleep (0x4448d7) Goroutine 11 - User: /usr/local/go/src/runtime/proc.go:310 time.Sleep (0x4448d7) Goroutine 12 - User: /usr/local/go/src/runtime/proc.go:310 time.Sleep (0x4448d7) Goroutine 13 - User: /usr/local/go/src/runtime/proc.go:310 time.Sleep (0x4448d7) Goroutine 14 - User: /usr/local/go/src/runtime/proc.go:310 time.Sleep (0x4448d7) Goroutine 15 - User: /usr/local/go/src/runtime/proc.go:310 time.Sleep (0x4448d7) Goroutine 17 - User: /usr/local/go/src/runtime/lock_futex.go:228 runtime.notetsleepg (0x409d04) * Goroutine 18 - User: ./test.go:47 main.myfun3 (0x495d93) (thread 5123) [17 goroutines]

命令goroutines查看所有goroutine,会发现Goroutine 18 - User: ./test.go:47 main.myfun3 (0x495d93) (thread 5123)这是我们写的代码,所以肯定时这个goroutine出现问题了。

(dlv) goroutine 18 Switched from 18 to 18 (thread 5123) 

切换到goroutine 18栈帧,当然当前所在的栈帧也是goroutine 18的栈帧,可以通过上一步中* Goroutine 18前面这个*可以看出来。

(dlv) bt 0 0x0000000000 in runtime.raise at /usr/local/go/src/runtime/sys_linux_amd64.s:150 1 0x000000000043c50b in runtime.dieFromSignal at /usr/local/go/src/runtime/signal_unix.go:428 2 0x000000000043c96d in runtime.sigfwdgo at /usr/local/go/src/runtime/signal_unix.go:631 3 0x000000000043bbf0 in runtime.sigtrampgo at /usr/local/go/src/runtime/signal_unix.go:289 4 0x0000000000 in runtime.sigtramp at /usr/local/go/src/runtime/sys_linux_amd64.s:357 5 0x0000000000 in runtime.sigreturn at /usr/local/go/src/runtime/sys_linux_amd64.s:449 6 0x000000000043c6aa in runtime.crash at /usr/local/go/src/runtime/signal_unix.go:520 7 0x0000000000429cd4 in runtime.fatalpanic at /usr/local/go/src/runtime/panic.go:874 8 0x0000000000 in runtime.gopanic at /usr/local/go/src/runtime/panic.go:722 9 0x000000000043c42c in runtime.panicmem at /usr/local/go/src/runtime/panic.go:199 10 0x000000000043c42c in runtime.sigpanic at /usr/local/go/src/runtime/signal_unix.go:394 11 0x0000000000495d93 in main.myfun3 at ./test.go:47 12 0x0000000000495d5a in main.myfun2 at ./test.go:42 13 0x0000000000453a91 in runtime.goexit at /usr/local/go/src/runtime/asm_amd64.s:1357 

查看当前的栈帧即breakpoints trace。发现11 0x0000000000495d93 in main.myfun3正是我们的代码出问题的地方。

(dlv) frame 11 > runtime.raise() /usr/local/go/src/runtime/sys_linux_amd64.s:150 (PC: 0x) Warning: debugging optimized function Frame 11: ./test.go:47 (PC: 495d93) 42: myfun3() 43: } 44: 45: func myfun3() { 

46: var p uintptr = 0 => 47: arr := (*int)(unsafe.Pointer(p)) 48: *arr = 1 49: fmt.Println(*arr) 50: }

在goroutine 18中,frame 11切换到具体11函数栈,发现问题出现在47行的代码,通过理解47行代码的上下文得知,不能操作地址为0的内存。

总结

  1. dlv功能特别强大,不仅能通过core dump文件定位到哪个goroutine崩溃,还可以具体定位到某行出错的代码,个人觉得调试Go core dump使用dlv比gdb好用。
  2. dlv还有很多命令,可以通过help查看命令的具体用法。
  3. 线上Go程序还是需要开启core dump的。
知秋君
上一篇 2024-07-03 15:32
下一篇 2024-07-03 15:32

相关推荐