如何debugging用Go语言编写的程序?

我如何debuggingGo程序? 我一直在使用Gedit Go IDE ,但没有debugging。 有没有办法通过我的代码来检查内存? 还是我坚持打印报表? 我可以使用OutputDebugString吗?

更新 :现在在GDB的Debugging Go Code文档中有一个官方页面。 这个答案写完以后发生了很大的变化,下面列出的几个限制已经被删除了。 我将这个答案的其余部分留给子孙后代,但是如果您想要debuggingGo代码,请点击上面的链接。

Go连接器现在发出可由gdb版本7.x解释的DWARFdebugging符号。

来自以上链接的博客文章突出显示:

您可以…

  • 在GDB版本7.x中加载一个Go程序
  • 按行列出所有Go,C和汇编源文件(Go运行时的一部分用C和汇编语言编写),
  • 按行设置断点并逐步执行代码,
  • 打印堆栈跟踪并检查堆栈帧,以及
  • find地址并打印大多数variables的内容。

还有一些不便之处:

  • 发布的DWARF代码是Mac OS X附带的GDB版本6.x无法读取的。我们很乐意接受修补程序,使DWARF输出与标准OS X GDB兼容,但在修复之前,您需要下载,构build,并安装GDB 7.x以在OS X下使用它。可以在http://sourceware.org/gdb/download/上find该源代码。; 由于OS X的特殊性,您需要使用chgrp procmod和chmod g + s将二进制文件安装在本地文件系统上。
  • 名字用包名来限定,因为GDB不理解Go包,所以你必须用全名来引用每个项。 例如,package main中名为v的variables必须在单引号中被称为“main.v”。 这样做的后果是variables和函数名称的Tab完成不起作用。
  • 词法范围信息有点混淆。 如果有多个相同名称的variables,则第n个实例将具有“#n”forms的后缀。 我们计划解决这个问题,但是它需要对编译器和链接器之间交换的数据进行一些更改。
  • 切片和stringvariables在运行时库中表示为它们的基础结构。 它们看起来像{data = 0x2aaaaab3e320,len = 1,cap = 1}。 对于片,您必须取消引用数据指针来检查元素。

有些事情不行:

  • 通道,函数,接口和映射variables不能被检查。
  • 只有Govariables注释了types信息; 运行时的Cvariables不是。
  • Windows和ARM二进制文件不包含DWARFdebugging信息,因此无法使用GDB进行检查。

新举措(2014年5月开始): derekparker/delve

Delve是一个Godebugging器,用Go编写
(尽pipe主要针对Linux,但是支持的是OsX支持 未知 在2016年得到支持 )

特征

  • 附加到已经运行的进程
  • 启动一个进程并开始debugging会话
  • 设置断点,单步,跨越function,打印variables内容

用法

debugging器可以通过三种方式启动:

编译,运行和附加一步:

 $ dlv -run 

提供要debugging的程序的名称,debugging器将为您启动它。

 $ dlv -proc path/to/program 

提供当前正在运行的进程的PID,debugging器将附加并开始会话。

 $ sudo dlv -pid 44839 

断点

Delve可以在debugging会话中通过断点命令插入断点,但是为了便于debugging,也可以调用runtime.Breakpoint() ,Delve将处理断点并在下一个源代码行停止程序。

另一个主动去debugging会话: hopwatch

与大多数debugging器不同,hopwatch要求您在程序中感兴趣的位置插入函数调用。 在这些程序位置,您可以告诉Hopwatch显示variables值并暂停程序(或goroutine)。
Hopwatch使用Websockets在您的程序和在HTML5页面中运行的debugging器之间交换命令。

(所以它仍然类似于“打印语句”,但用更优雅的方式来查看结果而不污染stdoutstderr

hopwatch

当程序调用Break函数时,它将debugging信息发送到浏览器页面,并等待用户交互。
使用DisplayPrintfDump (转换)function,您可以在浏览器页面上logging信息。
在hopwatch页面上,开发人员可以查看debugging信息并select恢复程序的执行。

与来源

也许一些一步一步的指令开始使用GDB将有所帮助。

我创build了silly.go包含:

 package main import "fmt" func x() { foo := 5 fmt.Printf("foo: %v\n", foo) } func main() { go x() fmt.Printf("Done.\n") } 

运行8g silly.go 8l -o silly silly.8 8g silly.go8l -o silly silly.8 ,我可以运行gdb silly 。 (我有“GNU gdb(Ubuntu / Linaro 7.2-1ubuntu11)7.2”,据我所知,Ubuntu 11.04 32位。)

然后我可以inputlistb 7break 7 for break 7 ),然后run 。 它停在第7行,我可以运行:

 (gdb) p foo $1 = 5 

看看Eclipse / CDTdebugging器和/或DDD是否可以与Go一起工作会很有趣。

GDB 7.5正式支持Go。

有一个名为ogle的实验性debugging器软件包。 不知道它有多好。

这是不幸的,但现在最好的办法是使用打印function。 内置的print和println可以工作,但是fmt中的函数有时可以更好的工作,这取决于你之后的信息。

另一种正在开发的debugging技术(Q4 2014): Go Execution Tracer

痕迹包含

  • 与goroutine调度有关的事件
    • goroutine开始在处理器上执行,
    • goroutine在同步原语上阻塞,
    • 一个门厅创build或取消阻止另一个门厅;
  • networking相关事件
    • networkingIO上的一个goroutine阻塞,
    • 在networkingIO上打开一个goroutine;
  • 系统调用相关的事件
    • 一个goroutine进入系统调用,
    • 系统调用返回一个goroutine;
  • 垃圾收集器相关的事件
    • GC启动/停止,
    • 并发扫描开始/停止; 和
  • 用户事件

“处理器”是指GOMAXPROCS的逻辑处理器。
每个事件包含事件ID,一个精确的时间戳,操作系统线程ID,处理器ID,goroutine ID,堆栈跟踪和其他相关信息(例如未阻止的goroutine id)。

https://lh5.googleusercontent.com/w0znUT_0_xbipG_UlQE5Uc4PbC8Mw1duHRLg_AKTOS4iS6emOD6jnQvSDACybOfCbuSqr2ulkxULXGOBQpZ2IejPHW_8NHufqmn8q5u-fF_MSMCEgu6FwLNtMvowbq74nA