Installation delve on macOS
直接看 文档
有一些要注意的,如果你的项目启用了 go mod,那么不要在项目目录下执行安装,因为这会把 delve 安装到项目目录下。
另外,记得配置好 go 的 bin 目录。
用法
首先进入项目目录,执行 dlv debug
,会进入 delve 的交互界面。
break main.go:29
在 29 行打下断点
breakpoints
打印出断点的信息
continue
运行程序,直到断点的位置
print son
打印程序中的变量 son
next
移至下一行代码
list
查看目前行的源码
on 1 print family
遇到断点时执行命令,这里的意思是在遇到第一个断点时,打印 family
restart
重启 debug 进程
用法
我们有如下的代码:
package main
import "fmt"
type Person struct {
Name string
Age int
}
func main() {
var me Person
me.Name = "Melvin"
me.Age = 31
var wife Person
wife.Name = "Raye"
wife.Age = 30
var daughter Person
daughter.Name = "Katherina"
daughter.Age = 11
var son Person
son.Name = "Vite"
son.Age = 10
var family []Person
family = append(family, me, wife, daughter, son)
fmt.Println(family)
birthdayToday(&daughter)
}
func birthdayToday(person *Person) {
person.Age = person.Age + 1
}
我们进入 dlv debug
之后依次输入如下命令:
b main.go:29 # 添加第1个断点
b main.go:31 # 添加第2个断点
on 1 print family # 遇到第 1 个断点时,打印 family
on 2 print family # 遇到第 2 个断点时,打印 family
r # 重启程序
c # 执行,直到断点 1
c # 执行,直到断点 2
这时候我们观察到结果就是,第一次打印的是
> main.main() ./main.go:29 (hits goroutine(1):1 total:1) (PC: 0x10c276b)
family: []main.Person len: 0, cap: 0, nil
第二次打印
> main.main() ./main.go:31 (hits goroutine(1):1 total:1) (PC: 0x10c28ab)
family: []main.Person len: 4, cap: 4, [
{Name: "Melvin", Age: 31},
{Name: "Raye", Age: 30},
{
Name: "Katherina",
Age: 11,},
{Name: "Vite", Age: 10},
]
更方便的命令
如果觉得上面的命令手打很麻烦,我们可以在项目目录下新建一个 txt 文件,比如名字叫 debug-config.txt
,内容如下:
b main.go:29
b main.go:31
on 1 print family
on 2 print family
进入 dlv debug
执行 source ../debug-config.txt
然后同上面一样,依次执行 c
, c
一样可以看到结果。
其他命令
clearall
删除所有断点
funcs main
查看所有函数
locals
打印所有变量
set son.Age = 3
修改变量的值
b main.main
在 main 函数上加断点
whatis son
son 的类型
s 和 n 的区别
n 是继续执行下一行代码,而当下一行代码是一个函数的时候,用 s 才能跳入到函数内部。
以上面的例子,我们用 n 已经之下到如下位置
> main.main() ./LearnGo/main.go:33 (PC: 0x10c2931)
28:
29: family = append(family, me, wife, daughter, son)
30:
31: fmt.Println(family)
32:
=> 33: birthdayToday(&daughter)
34: }
35:
36: func birthdayToday(person *Person) {
37: person.Age = person.Age + 1
38: fmt.Println(person.Age)
这时候,如果继续按 n 就会跳到下一行,也就是函数的结尾,只有按 s,单步跟踪,才能进入到 birthdayToday
函数的内部继续调试。
如果项目结构复杂怎么办
我这里有一个结构相对复杂的项目,也就是按照 这篇文章 来做的项目结构。
这时候你要进入项目的目录,然后执行 dlv debug ./cmd/server/main.go
就能正常调试整个项目了。
相关阅读
再忘记用法的时候,建议重新读下面的文章,本文都是摘抄的。