Go 博客
调试 Go 代码(状态报告)
在调试方面,没有什么比几个策略性的打印语句来检查变量或一个放置得当的 panic 来获取堆栈跟踪更有效了。但是,有时您可能没有耐心或源代码,在这种情况下,一个好的调试器将非常宝贵。这就是为什么在过去的几个版本中,我们一直在改进 Go 的 gc 链接器 (6l, 8l) 对 GDB(GNU 调试器)的支持。
在最新版本 (2010-11-02) 中,6l 和 8l 链接器在写入 ELF(Linux、FreeBSD)或 Mach-O(Mac OS X)二进制文件时会发出 DWARF3 调试信息。DWARF 代码足够丰富,让您执行以下操作:
- 在 GDB 7.x 版本中加载 Go 程序,
- 按行列出所有 Go、C 和汇编源文件(Go 运行时的部分是用 C 和汇编编写的),
- 按行设置断点并逐步执行代码,
- 打印堆栈跟踪并检查堆栈帧,以及
- 查找大多数变量的地址并打印其内容。
仍然有一些不便之处
- 发出的 DWARF 代码无法被随 Mac OS X 提供的 GDB 6.x 版本读取。我们很乐意接受补丁,以使 DWARF 输出与标准的 OS X GDB 兼容,但在修复之前,您需要下载、构建并安装 GDB 7.x 才能在 OS X 下使用它。源代码可以在 http://sourceware.org/gdb/download/ 找到。由于 OS X 的特殊性,您需要使用
chgrp procmod
和chmod g+s
将二进制文件安装到本地文件系统上。 - 名称使用包名限定,由于 GDB 不理解 Go 包,您必须通过其完整名称来引用每个项。例如,包
main
中名为v
的变量必须引用为'main.v'
,用单引号括起来。这样做的结果是,变量和函数名的制表符完成不起作用。 - 词法作用域信息有些模糊。如果存在多个同名变量,则第 n 个实例将带有
'#n'
形式的后缀。我们计划修复这个问题,但这需要对编译器和链接器之间交换的数据进行一些更改。 - 切片和字符串变量表示为运行时库中它们的基础结构。它们看起来像是
{data = 0x2aaaaab3e320, len = 1, cap = 1}.
对于切片,您必须取消引用数据指针以检查元素。
有些东西还没有实现
- 无法检查通道、函数、接口和映射变量。
- 只有 Go 变量被注释了类型信息;运行时的 C 变量没有。
- Windows 和 ARM 二进制文件不包含 DWARF 调试信息,因此无法使用 GDB 检查。
在接下来的几个月里,我们打算通过更改编译器和链接器或使用 GDB 的 Python 扩展来解决这些问题。在此期间,我们希望 Go 程序员能够更好地使用这个众所周知的调试工具。
附注:DWARF 信息也可以被除 GDB 之外的其他工具读取。例如,在 Linux 上,您可以将其与 sysprof 系统范围的分析器一起使用。
下一篇文章:Go:一年前的今天
上一篇文章:真正的 Go 项目:SmartTwitter 和 web.go
博客索引