Tutorials 开发工具

以 GoLand 调试 – 高级调试功能

以前我们解决了诸如配置调试器和调试会话如何控制调试器执行流程和配置断点等问题,这些是 2019.1 版中的最新改进

在今天的文章中,我们将讨论 GoLand 的两个高级调试功能:核心转储调试 (Core Dump debugging) 和使用 可逆调试器 Mozilla rr

调试核心转储

核心转储是应用程序运行到特定时间点的内存快照。它们可以帮助我们可视化所有现存 goroutine,包含变量的所有值,以及每个有效 goroutine 的当前执行点。

现在,GoLand 仅支持 Linux 系统上的核心转储,但可以在任何操作系统上读取和分析它们。有两种方法可以获得核心转储。

 如果我们想要查看进程因崩溃而终止时的内存值,我们需要将ulimit 设置为高得合理,例如 sudo ulimit -c unlimited ,并且配置以下环境变量GOTRACEBACK=crash 。这将确保 Go 应用程序崩溃时打印了堆栈跟踪并且写入了核心转储文件。

为了能够从正在运行的进程中获取核心转储而不使其崩溃,我们需要在系统上安装 gdb 且运行这些命令:

sudo ulimit -c unlimited
echo 0 | sudo tee -a /proc/sys/kernel/yama/ptrace_scope

请注意,该值将在系统重启时重置,需要再次配置。

为了生成和使用核心转储,我们需要配置 IDE,以便将二进制文件保存在已知位置,比如我们的项目根目录。

之后,我们可以像往常一样启动应用程序,并且开始向它发送请求。

接下来,确定应用程序的进程 ID 后,可以调用 gcore <pid>  并且获得转储文。

要研究 IDE 中的核心转储,我们可以使用从远程服务器生成的或者运行上述命令生成的二进制文件和核心转储。然后转到 运行 | 打开核心转储 (Run | Open Core Dump )… 并且选择可执行文件和核心转储文件。这样将打开调试器界面,让您查看正在运行的 goroutine、线程、所有变量的值的列表。可以使用 Evaluate 功能来理解应用程序当前在做什么。

使用核心转储可以帮助您确定 goroutine 被卡在哪里、它们有多少,以及发生问题时它们在内存中的值。

Mozilla rr 可逆调试器

然而,使用核心转储是一个静态过程。有时候bug很难再现,需要很多调试会话才能重现,然后再经过更多次调试来查看问题是否修复。

进入可逆调试器。这些调试器不仅允许我们在执行中前进,而且还可以返回并且有效地撤消步骤之间的所有操作。Delve 是 GoLand 使用的 Go 调试器,通过使用 Mozilla 的 rr 项目以支持这类功能。从 rr 项目的定义可以看出,其使命是允许“在调试器中重复执行失败的执行,直到完全理解它为止”。

使用 rr 的另一个优势在于,它在录制会话期间的执行开销很低。这意味着它可以用于生产系统或类似于生产的金丝雀系统 (canary systems),以便捕获无法以其他方式再现的错误,然后在开发环境中舒适地调查。

我们看看它的运行情况。开始前,应该提前了解那些对于 rr 可以在哪里运行的严格限制。

它只能在 Linux 上运行,并且对硬件/虚拟机功能有一些限制。这些会影响调试解决方案的有用性。但是,一旦环境满足要求,它将成为最强大的解决方案之一。

安装 rr 后,我们需要运行几个命令,以便 rr 可以执行录制部分:

echo -1 | sudo tee -a /proc/sys/kernel/perf_event_paranoid
echo 0 | sudo tee -a /proc/sys/kernel/kptr_restrict

这些设置不是永久的,重启机器后需要再次应用这些设置。

点击主函数旁边的绿色箭头,然后选择 记录和调试 (Record and Debug…) 这将启动要求的编译步骤,然后调试器在后端使用 rr

对于设计为连续运行的应用程序,例如示例代码中的Web服务器,我们需要停止调试器,然后选择 Run | 调试保存的跟踪 (Debug Saved Trace…) 默认将选择最新的 rr 会话,所以我们可以点击“确定”按钮开始调试会话。

对于已经确定终止的应用程序,例如 CLI 应用程序,GoLand 将自动启动重播会话。

这是调试会话与常规调试会话的不同之处。在会话的“记录”期间,调试器不会在断点处停止;它只会重播所有动作。如果没有设置断点,则调试器将结束,我们需要手动重放上一个会话,同时需要存在断点 – 否则将完成重播会话,中途不会停止,直到退出。

如果存在断点,则调试器将在断点停止,并且它将提供与正常调试器会话类似的体验。

至于“可逆”部分,这是使用 rr 的最佳之处。如果在当前执行点之前放置断点,那么我们可以使用“倒带 (Rewind)”功能返回到断点,并从那里重试执行。监视变量或评估表达式等功能也会起作用。

希望本文能帮助您了解这个新工具的强大之处,它可以协助你加快查找和修复应用程序中的错误。

和往常一样,如果您有任何意见或想了解更多相关信息,欢迎您通过我们的官方微博和微信告诉我们您对此的看法, 或在YouTrack写下您的反馈或问题。

原文发表于2019年3月4日,作者 Florin Pățan

image description

Discover more