Go:使用Delve和Core Dump来调试

ℹ️ 本文基于Go Delve 1.4.1

core dump(核心转储)是包含程序内存意外终止快照的文件。它用于事后调试以了解崩溃原因和其中涉及的变量。Go提供了环境变量GOTRACEBACK 用于控制程序崩溃时生成的输出。 此变量还可以强制生成core dump,从而可以进行调试。

GOTRACEBACK

GOTRACEBACK 控制程序崩溃时输出的详细程度。 它可以采用不同的值:

  • none 不显示任何goroutine栈trace。
  • single, 默认选项,显示当前goroutine栈trace。
  • all 显示所有用户创建的goroutine栈trace。
  • system 显示所有goroutine栈trace,甚至运行时的trace。
  • crash 类似 system, 而且还会生成 core dump。

最后一个选项使我们能够在发生崩溃的情况下调试程序。 如果没有足够的日志,或者崩溃无法重现,这可能是一个不错的选择。 让我们以以下程序为例:

该程序将很快崩溃:

我们无法从栈trace中分辨出崩溃所涉及的值。增加日志或许是一种解决方案,但是我们并不总是知道在何处添加日志。当问题无法重现时,很难编写测试案例来确保问题被修复。我们可以在添加日志和运行程序之间进行迭代,直到它崩溃并查看到运行后可能的原因。

让我们再次使用GOTRACEBACK=crash运行它。 由于我们现在已打印出所有goroutine,包括运行时,因此输出更加详细。 并输出core dump:

core dump 是通过 SIGABRT 信号触发。

core dump 可以通过delve或者gdb。

Delve

Delve是使用Go编写的Go程序的调试器。 它可以通过在用户代码以及运行时中的任意位置添加断点来逐步调试,甚至可以使用以二进制文件和core dump为参数的命令 dlv core 调试core dump。

一旦命令运行,我们就可以开始与core dump进行交互了:

dlv 命令bt打印栈trace并显示程序生成的panic恐慌。 然后,我们可以使用 frame 9命令访问第9帧:

最后,命令locals打印局部变量,以帮助了解崩溃所涉及的值:

通道满了, 随机生成的数字为203,300。关于变量 sum ,可以使用打印包变量命令vars 打印:

如果看不到局部变量n的值,请确保使用编译器标志-N -l来构建二进制文件,它会禁用编译器优化,编译器优化可能会使调试更加困难。这是完整的命令:go build -gcflags=all="-N -l"。 另外,不要忘记运行ulimit -c unlimited,该选项-c 定义core dump的最大大小。

编译整理自  Go: Debugging with Delve & Core Dumps

张贴在Go标签:

版权声明: 本文为【陈思敏捷】的原创文章。
原文链接:【https://www.chenjie.info/2447】。原文标题:【Go:使用Delve和Core Dump来调试】。文章转载请联系作者。

欢迎订阅我的公众号,文章更新早知道


发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据