Go:使用 Delve 和 Core Dump 调试代码

dust347 · 2020-08-18 15:48:10 · 2261 次点击 · 预计阅读时间 3 分钟 · 大约8小时之前 开始浏览    
这是一个创建于 2020-08-18 15:48:10 的文章,其中的信息可能已经有所发展或是发生改变。

由 Renee French 创作的原始 Go Gopher 为“ Go Go 之旅”创建的插图。 ℹ️ 这篇文章基于 Go Delve 1.4.1。

core dump 是一个包含着意外终止的程序其内存快照的文件。这个文件可以被用来事后调试(debugging)以了解为什么会发生崩溃,同时了解其中涉及到的变量。通过 GOTRACEBACK,Go 提供了一个环境变量用于控制程序崩溃时生成的输出信息。这个变量同样可以强制生成 core dump,从而使调试成为可能。

GOTRACEBACK

GOTRACEBACK 控制着当程序崩溃时输入的详细程度。它可以使用不同的值:

  • none 不显示任何 Goroutine 的堆栈信息。
  • single,默认选项,显示当前 Goroutine 的堆栈信息。
  • all 显示所有用户创建的 Goroutine 的堆栈信息。
  • system 显示所有 Goroutine 的堆栈信息,即使是来自运行时的 goroutine。
  • crashsystem 类似,但是会生成 core dump。

最后的那个选项,给了我们在程序崩溃的情况下,调试我们程序的能力。如果没有足够的日志,或者崩溃无法复现时,这是一个好的选择。让我们以下面的程序为例:

这个程序会很快崩溃:

从堆栈信息中我们无法获知那个值涉及了程序的崩溃。增加日志是一个解决办法,但我们无法一直知道要在哪里加日志。当问题无法复现的时候,编写测试用例以确保问题被修复是十分困难的。我们可以不断重复增加日志和运行程序的步骤,直到程序崩溃,再查看可能的原因后再运行。

设置 GOTRACEBACK=crash 后再次运行。输出信息更加详细,因为现在所有的 Goroutine 信息打印了出来,包括运行时的。无论如何,我们现在有了 core dump。

core dump 通过 SIGABRT 信号触发,该信号生成 core dump 作为处置

core dump 可以被诸如 Go delve 或者 GBD 的调试信息分析。

Delve

Delve 是用 Go 语言编写的 Go 程序调试器。它允许通过在用户代码和运行时代码的任意位置加断点来逐步调试,甚至通过 dlv core 命令来调试 core dump,这个命令以二进制和 core dump 为参数。

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

dlv 命令 bt 打印堆栈信息并且显示程序生成的 panic 信息。之后,我们可以通过 frame 9 命令来访问 9 号帧:

最终,用 locals 命令打印本地变量,来帮助了解哪个变量与崩溃有关:

channel 是满的,并且生成的随机数是 203,300。而对于变量 sum,可以通过命令 vars 打印出它的内容,该命令用于打印包级别变量:

如果没有看到本地变量 n ,请确保使用编辑标志 -N-l 来构建二进制程序,这些标志禁用编译器优化,而这些优化会是调试更加困难。完整的编译命令是:go build -gcflags=all="-N -l" 不要忘记运行 ulimit -c unlimited,选项 -c 定义了 core dump 的最大尺寸。


via: https://medium.com/a-journey-with-go/go-debugging-with-delve-core-dumps-384145b2e8d9

作者:Vincent Blanchon  译者:dust347  校对:polaris1119

本文由 GCTT 原创编译,Go语言中文网 荣誉推出


有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2261 次点击  
加入收藏 微博
被以下专栏收入,发现更多相似内容
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传