通过dlv简单分析Go coredump文件

通过dlv简单分析Go coredump文件文章目录 dlv 调试工具安装调试 Go 程序 coredump 文件 Linux 环境配置 Go 环境配置测试用例总结 dlv 调试工具安装 Github 地址 https github com go delve delveLinux 安装 参考地址 https github com go delve delve blob master Documentatio installation linux install md 安装步骤 安装前确保 GOPATH 已经安装 gitclonehttp git

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的。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/213210.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午6:20
下一篇 2026年3月18日 下午6:20


相关推荐

  • oracle中varchar和char的区别_char跟varchar

    oracle中varchar和char的区别_char跟varchar1.varchar2把所有字符都占两字节处理(一般情况下),varchar只对汉字和全角等字符占两字节,数字,英文字符等都是一个字节;2.VARCHAR2把空串等同于null处理,而varchar仍按照空串处理;3.VARCHAR2字符要用几个字节存储,要看数据库使用的字符集,大部分情况下建议使用varchar2类型,可以保证更好的兼容性。注意:在oracle中varchar2的最大长…

    2025年7月24日
    12
  • oracle拼接字符串函数_Oracle字符串转换为数值

    oracle拼接字符串函数_Oracle字符串转换为数值1.使用“||”进行字符串拼接。select’a’||’b’||’c’fromdual;’A’||’B’||’C’—————-abc2.使用CONCAT()函数进行字符串拼接。selectconcat(‘a’,’b’)fromdual;CONCAT(‘A’||’B’)—————–ab如果CONCAT中连接的值不是字符…

    2026年2月5日
    3
  • 404notfound软件下载_浏览器打开网址404

    404notfound软件下载_浏览器打开网址404当网上的那些修改程序池的方法,无法解决此问题时,可以尝试修改以下的参数:1.控制面板–&amp;gt;程序–&amp;gt;启用或关闭Windows功能–&amp;gt;InternetInformationServices–&amp;gt;Web管理工具–&amp;gt;子项全部勾选上.2.InternetInformationServices–&amp;gt;应用程序开发功能–&amp;gt;子项全部勾选上.重

    2025年6月7日
    4
  • 蓝桥杯集锦02(python3)

    蓝桥杯集锦02(python3)

    2021年4月17日
    198
  • python爬虫-数据解析(正则)

    python爬虫-数据解析(正则)

    2021年4月15日
    166
  • 博客大巴(BlogBus)

    博客大巴(BlogBus)更新日志 2013 年 7 月 22 日 blogbus 已经修复好了 本插件也制作好了 2013 年 7 月 21 日 今天发现大巴的后台更新了 几次重新抓包都没有成功 IE 根本无法发布 等待他们的改版修复 ing 正题使用说明今天我们来演示一个 x3 的发布插件 blogbus 发布插件 总所周知 blogbus 的管理是十分严格的 对于登录 获取分类 到发布文章 都是经过了加密解密

    2026年3月20日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号