Delve 是语言源码一个简单、强大和易用的试器 Go 语言源代码层级的调试器,也是语言源码 Go 官方推荐使用的调试器。 Delve 安装非常简单,试器如果读者朋友使用的语言源码是 Go 1.16 或更高版本,可以直接使用 go install 安装: 如果读者朋友们使用的试器是低于 Go 1.16 的版本,可是语言源码先下载 Delve 源码,然后使用 go install 安装: git clone https://github.com/go-delve/delve cd delve 安装完成之后,试器可以使用 go help install 查看 dlv 可执行文件的语言源码详细位置。我建议读者朋友们将 dlv可执行文件,试器配置到 PATH 环境变量。语言源码 需要注意的试器是,如果读者朋友们使用的语言源码是 macOS,还需要安装命令行开发工具: 为了避免每次使用 dlv 都需要授权允许使用 debugger,试器建议读者朋友们开启开发者模式: 在完成 Part 02 中的语言源码所有操作之后,我们使用 dlv version 检查 dlv 可执行程序是否已可以使用。香港云服务器 我们可以使用 dlv 的任意可用命令启动一个调式会话,比较常用的命令是 dlv debug, dlv exec 和 dlv test。限于篇幅,本文我们介绍 dlv debug 的使用方法。 示例代码: package main import ( "fmt" ) func main() { a := 1 b := 2 c := sum(a, b) fmt.Println(c) } func sum(a, b int) int { res := a + b return res 阅读上面这段我们将用于调试会话的代码示例,它包含一个 main 函数和一个 sum 函数,main 函数中定义变量 a 和变量 b,调用 sub 函数,并将返回结果赋值给变量 c,最后打印变量 c 的值。 启动一个调试会话: [root@VM-8-14-centos work]# dlv debug Type help for list of commands. 阅读上面这段代码,我们使用 dlv debug 启动一个调试会话,在没有任何参数的情况下,Delve 编译并开始调试当前目录中的 main 包。 我们也可以指定一个文件名,Delve 将会编译该指定文件的 main 包,并启动一个调试会话。 [root@VM-8-14-centos work]# dlv debug main.go Type help for list of commands. 调试会话启动后,我们可以使用调试命令进行调试程序。 list 命令: dlv debug Type help for list of commands. (dlv) list main.main Showing /work/main.go:7 (PC: 0x49670a) 2: 3: import ( 4: "fmt" 5: ) 6: 7: func main() { 8: a := 1 9: b := 2 10: c := sum(a, b) 11: fmt.Println(c) 12: } (dlv) list ./main.go:7 Showing /work/main.go:7 (PC: 0x49670a) 2: 3: import ( 4: "fmt" 5: ) 6: 7: func main() { 8: a := 1 9: b := 2 10: c := sum(a, b) 11: fmt.Println(c) 12: } 调试会话启动后,我们可以使用 list 命令列出指定位置的源码,包含两种方式,云服务器第一种方式是 .,第二种方式是 :。 break 命令: dlv debug Type help for list of commands. (dlv) break main.main Breakpoint 1 set at 0x49670a for main.main() ./main.go:7 我们可以使用 break 命令添加断点,和 list 命令一样,添加断点的位置,也可以使用上述两种方式。 我们可以使用 breakpoints 命令,列出所有断点,可以使用 clear 命令删除指定断点,可以使用 clearall 删除所有断定。 continue、next、step、stepout 和 print 命令: dlv debug Type help for list of commands. (dlv) break main.main Breakpoint 1 set at 0x49670a for main.main() ./main.go:7 (dlv) continue > main.main() ./main.go:7 (hits goroutine(1):1 total:1) (PC: 0x49670a) 2: 3: import ( 4: "fmt" 5: ) 6: => 7: func main() { 8: a := 1 9: b := 2 10: c := sum(a, b) 11: fmt.Println(c) 12: } (dlv) next > main.main() ./main.go:8 (PC: 0x496718) 3: import ( 4: "fmt" 5: ) 6: 7: func main() { => 8: a := 1 9: b := 2 10: c := sum(a, b) 11: fmt.Println(c) 12: } 13: (dlv) next > main.main() ./main.go:9 (PC: 0x496721) 4: "fmt" 5: ) 6: 7: func main() { 8: a := 1 => 9: b := 2 10: c := sum(a, b) 11: fmt.Println(c) 12: } 13: 14: func sum(a, b int) int { (dlv) next > main.main() ./main.go:10 (PC: 0x49672a) 5: ) 6: 7: func main() { 8: a := 1 9: b := 2 => 10: c := sum(a, b) 11: fmt.Println(c) 12: } 13: 14: func sum(a, b int) int { 15: res := a + b (dlv) print a 1 (dlv) print b 2 (dlv) step > main.sum() ./main.go:14 (PC: 0x4967e0) 9: b := 2 10: c := sum(a, b) 11: fmt.Println(c) 12: } 13: => 14: func sum(a, b int) int { 15: res := a + b 16: return res 17: } (dlv) next > main.sum() ./main.go:15 (PC: 0x496800) 10: c := sum(a, b) 11: fmt.Println(c) 12: } 13: 14: func sum(a, b int) int { => 15: res := a + b 16: return res 17: } (dlv) next > main.sum() ./main.go:16 (PC: 0x49680f) 11: fmt.Println(c) 12: } 13: 14: func sum(a, b int) int { 15: res := a + b => 16: return res 17: } (dlv) next > main.main() ./main.go:10 (PC: 0x496739) Values returned: ~r0: 3 5: ) 6: 7: func main() { 8: a := 1 9: b := 2 => 10: c := sum(a, b) 11: fmt.Println(c) 12: } 13: 14: func sum(a, b int) int { 15: res := a + b (dlv) next > main.main() ./main.go:11 (PC: 0x49673e) 6: 7: func main() { 8: a := 1 9: b := 2 10: c := sum(a, b) => 11: fmt.Println(c) 12: } 13: 14: func sum(a, b int) int { 15: res := a + b 16: return res (dlv) print c 3 阅读上面这段代码,我们使用 Delve 添加断点后,执行 continue 命令,程序将执行到断点位置;执行 next 命令,程序继续执行下一行代码;执行 step 命令,程序步入到调用函数内部;执行 stepout 命令,程序步出到调用函数的调用位置;执行 print 命令,打印指定参数的值。 读者朋友们使用以上命令,可以满足大部分调试场景。为了方便理解,以上示例中使用的命令都没有使用简写形式,在实际使用时,使用简写形式会更加便捷。源码库 简写形式: 本文我们简单介绍 Go 语言调试器 Delve 的基本使用方式,读者朋友们可以在程序调试时将 Delve 使用起来,替换使用 print 打印的形式调试代码。01介绍