如何调试Go程序?我一直在使用Gedit Go IDE,但它没有调试。有没有办法通过我的代码和检查内存?还是我坚持打印报表?我可以使用OutputDebugString吗?
答案 0 :(得分:22)
更新:Debugging Go Code with GDB上的文档中现在有一个官方页面。自写这篇答案以来,已经发生了很大变化,下面列出的一些限制已被删除。我将剩余的答案留给后代,但如果你想调试Go代码,请点击上面的链接。
Go链接器now emit DWARF调试符号,可由gdb版本7.x解释。
从上面链接的博文中突出显示:
你可以......
仍有一些不便之处:
有些事情不起作用:
答案 1 :(得分:13)
新计划(2014年5月开始):derekparker/delve
Delve是一个 Go调试器,用Go编写 (主要针对Linux,OsX支持即将到来,Windows支持
unknownsupported in 2016)
- 附加到已在运行的流程
- 启动流程并开始调试会话
- 设置断点,单步,跳过函数,打印变量内容
调试器可以通过三种方式启动:
一步编译,运行和附加:
$ dlv -run
提供要调试的程序的名称,调试器将为您启动它。
$ dlv -proc path/to/program
提供当前正在运行的进程的pid,调试器将附加并开始会话。
$ sudo dlv -pid 44839
Delve可以在调试会话中通过断点命令插入断点,但是为了便于调试,您还可以调用
runtime.Breakpoint()
,Delve将处理断点并在下一个源代码行停止程序。
答案 2 :(得分:9)
进行调试会话的另一项举措:hopwatch
与大多数调试器不同,hopwatch要求您在程序中的兴趣点插入函数调用。在这些程序位置,您可以告诉Hopwatch显示变量值并暂停程序(或goroutine) Hopwatch使用Websockets在程序和HTML5页面中运行的调试器之间交换命令。
(所以它仍然类似于“打印声明”,但更优雅地查看结果而不会污染stdout
和stderr
)
当程序调用Break函数时,它会将调试信息发送到浏览器页面并等待用户交互 使用
Display
,Printf
或Dump
(go-spew
)功能,您可以在浏览器页面上记录信息。
在hopwatch页面上,开发人员可以查看调试信息并选择继续执行程序。
答案 3 :(得分:8)
也许有关GDB入门的一步一步说明会有所帮助。
我创建了包含:
的silly.gopackage 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
后,我可以运行gdb silly
。 (据我所知,我有“GNU gdb(Ubuntu / Linaro 7.2-1ubuntu11)7.2”,Ubuntu 11.04 32位。)
然后我可以输入list
,b 7
(break 7
的缩写)和run
。它停在第7行,我可以运行:
(gdb) p foo
$1 = 5
看看Eclipse / CDT调试器和/或DDD是否适用于Go会很有趣。
答案 4 :(得分:4)
GDB 7.5正式支持Go。
答案 5 :(得分:3)
有一个名为ogle的实验性调试程序包。不确定它的效果如何。
答案 6 :(得分:3)
这很不幸,但现在最好的方法是使用打印功能。内置的print和println可以工作,但fmt中的功能有时会更好,具体取决于你所追求的信息。
答案 7 :(得分:3)
正在开发的另一种调试技术(2014年第4季度):Go Execution Tracer
跟踪包含
- 与goroutine计划相关的事件:
- goroutine开始在处理器上执行,
- 同步原语上的goroutine块,
- goroutine创建或解除另一个goroutine;
- 与网络相关的活动:
- 网络IO上的goroutine块,
- goroutine在网络IO上被解锁;
- 系统调用相关事件:
- goroutine进入系统调用,
- 从系统调用返回goroutine;
- 垃圾收集器相关事件:
- GC启动/停止,
- 并发扫描开始/停止;和
- 用户事件。
“处理器”是指逻辑处理器,单位为
GOMAXPROCS
每个事件包含事件ID,精确时间戳,OS线程ID,处理器ID,goroutine id,堆栈跟踪和其他相关信息(例如,未阻止的goroutine id)。