DLV
在 Go 编程语言中,DLV (Delve) 是一种用于调试 Go 代码的工具。DLV 是一个开源的调试器,它可以帮助开发者在编写和调试 Go 程序时识别和解决问题。以下是关于使用 DLV 进行 Go 代码调试的一些重要信息:
- 
设置断点: 开发者可以在他们的 Go 代码中设置断点,以便在程序执行时停止并检查变量、堆栈跟踪和其他调试信息。
 - 
单步执行: DLV 允许用户逐行或逐过程地执行代码,以便一步一步地跟踪程序的执行流程。
 - 
查看变量: 开发者可以使用 DLV 查看当前执行上下文中的变量的值,以便了解程序的状态。
 - 
检查堆栈: DLV 允许用户查看当前函数的调用堆栈,以识别可能的错误或异常。
 - 
多线程调试: Go 支持并发编程,DLV 也可以用于调试多线程应用程序,以帮助解决并发问题。
 - 
远程调试: DLV 支持远程调试,这意味着您可以在远程服务器上调试运行中的 Go 代码。
 - 
集成编辑器: DLV 可以与一些流行的集成开发环境(IDE)和文本编辑器集成,例如 Visual Studio Code(VS Code)和 GoLand。
 
安装
使用install安装,之后会安装在GOPATH目录下
go install  github.com/go-delve/delve/cmd/dlv
如果在/etc/profile下设置了PATH则可以直接使用,没有则需要设置全局变量
export PATH=$PATH:/c/Users/54225/go/bin/
运行
这里展示一个运行demo
#cat main.go
package main
import "fmt"
func main() {
	i := []int{1, 2, 3, 4, 5, 6, 7, 8}
	j := "this is dlv"
	for _, v := range i {
		fmt.Println(v)
	}
	fmt.Println(j)
}
执行debug运行,执行完毕后就是这个样子,此时程序还没有被运行
$ dlv.exe debug ch19/main.go
Type 'help' for list of commands.
(dlv)
执行c运行程序,发现程序立刻执行完毕了,这里的c是命令call简写
$ dlv.exe debug ch19/main.go 
Type 'help' for list of commands.
(dlv) c
1
2
3
4
5
6
7
8
this is dlv
Process 20804 has exited with status 0
执行b标记断点,断点表示执行到这边停顿
$ dlv.exe debug ch19/main.go 
Type 'help' for list of commands.
(dlv) b main.go:5
Breakpoint 1 set at 0xf49812 for main.main() C:/Users/54225/AppData/Roaming/MobaXterm/home/project/learning/ch19/main.go:5
在标记断点后,需要运行程序才可以触发断点
$ dlv.exe debug ch19/main.go 
Type 'help' for list of commands.
(dlv) b main.go:5
Breakpoint 1 set at 0xf49812 for main.main() C:/Users/54225/AppData/Roaming/MobaXterm/home/project/learning/ch19/main.go:5
(dlv) c
> main.main() C:/Users/54225/AppData/Roaming/MobaXterm/home/project/learning/ch19/main.go:5 (hits goroutine(1):1 total:1) (PC: 0xf49812)
     1: package main
     2:
     3: import "fmt"
     4:
=>   5: func main() {
     6:         i := []int{1, 2, 3, 4, 5, 6, 7, 8}
     7:         j := "this is dlv"
     8:
     9:         for _, v := range i {
    10:                 fmt.Println(v)
显示在main.go第5行停顿,此时按n继续
(dlv) n
> main.main() C:/Users/54225/AppData/Roaming/MobaXterm/home/project/learning/ch19/main.go:6 (PC: 0xf49829)
     1: package main
     2:
     3: import "fmt"
     4:
     5: func main() {
=>   6:         i := []int{1, 2, 3, 4, 5, 6, 7, 8}
     7:         j := "this is dlv"
     8:
     9:         for _, v := range i {
    10:                 fmt.Println(v)
    11:         }
发现执行到下一行了,此时打印i变量看看,发现没有找到这个变量,那是因为这一行没执行,需要到下一行打印才能生效
(dlv) p i
Command failed: could not find symbol value for i
在下一行打印生效了
(dlv) n
> main.main() C:/Users/54225/AppData/Roaming/MobaXterm/home/project/learning/ch19/main.go:7 (PC: 0xf498dc)
     2:
     3: import "fmt"
     4:
     5: func main() {
     6:         i := []int{1, 2, 3, 4, 5, 6, 7, 8}
=>   7:         j := "this is dlv"
     8:
     9:         for _, v := range i {
    10:                 fmt.Println(v)
    11:         }
    12:
(dlv) p i
[]int len: 8, cap: 8, [1,2,3,4,5,6,7,8]
一直按n到fmt.Println(v)这一行,这是一个包函数,可以按s进入下一层
(dlv) n
> main.main() C:/Users/54225/AppData/Roaming/MobaXterm/home/project/learning/ch19/main.go:10 (PC: 0xf49965)
     5: func main() {
     6:         i := []int{1, 2, 3, 4, 5, 6, 7, 8}
     7:         j := "this is dlv"
     8:
     9:         for _, v := range i {
=>  10:                 fmt.Println(v)
    11:         }
    12:
    13:         fmt.Println(j)
    14: }
(dlv) s
> fmt.Println() C:/Users/54225/AppData/Roaming/MobaXterm/home/go1.20.5.windows-amd64/go/src/fmt/print.go:313 (PC: 0xf444ca)
   308: }
   309:
   310: // Println formats using the default formats for its operands and writes to standard output.
   311: // Spaces are always added between operands and a newline is appended.
   312: // It returns the number of bytes written and any write error encountered.
=> 313: func Println(a ...any) (n int, err error) {
   314:         return Fprintln(os.Stdout, a...)
   315: }
   316:
   317: // Sprintln formats using the default formats for its operands and returns the resulting string.
   318: // Spaces are always added between operands and a newline is appended.
进入下一层后,看到想看的逻辑了,想要返回到主函数,需要按n,结束这一次返回
(dlv) n
> fmt.Println() C:/Users/54225/AppData/Roaming/MobaXterm/home/go1.20.5.windows-amd64/go/src/fmt/print.go:314 (PC: 0xf444ff)
   309:
   310: // Println formats using the default formats for its operands and writes to standard output.
   311: // Spaces are always added between operands and a newline is appended.
   312: // It returns the number of bytes written and any write error encountered.
   313: func Println(a ...any) (n int, err error) {
=> 314:         return Fprintln(os.Stdout, a...)
   315: }
   316:
   317: // Sprintln formats using the default formats for its operands and returns the resulting string.
   318: // Spaces are always added between operands and a newline is appended.
   319: func Sprintln(a ...any) string {
(dlv) n
1
> main.main() C:/Users/54225/AppData/Roaming/MobaXterm/home/project/learning/ch19/main.go:10 (PC: 0xf49a05)
Values returned:
        n: 2
        err: error nil
     5: func main() {
     6:         i := []int{1, 2, 3, 4, 5, 6, 7, 8}
     7:         j := "this is dlv"
     8:
     9:         for _, v := range i {
=>  10:                 fmt.Println(v)
    11:         }
    12:
    13:         fmt.Println(j)
    14: }
想要结束此次任务,不看断点了,可以按c
(dlv) n
1
> main.main() C:/Users/54225/AppData/Roaming/MobaXterm/home/project/learning/ch19/main.go:10 (PC: 0xf49a05)
Values returned:
        n: 2
        err: error nil
     5: func main() {
     6:         i := []int{1, 2, 3, 4, 5, 6, 7, 8}
     7:         j := "this is dlv"
     8:
     9:         for _, v := range i {
=>  10:                 fmt.Println(v)
    11:         }
    12:
    13:         fmt.Println(j)
    14: }
(dlv) c
2
3
4
5
6
7
8
this is dlv
Process 20716 has exited with status 0
此时程序已经执行完毕了,但是debug模式没有退出,可以按r重新启动
(dlv) r
Process restarted with PID 25312
(dlv) c
> main.main() C:/Users/54225/AppData/Roaming/MobaXterm/home/project/learning/ch19/main.go:5 (hits goroutine(1):1 total:1) (PC: 0xf49812)
     1: package main
     2:
     3: import "fmt"
     4:
=>   5: func main() {
     6:         i := []int{1, 2, 3, 4, 5, 6, 7, 8}
     7:         j := "this is dlv"
     8:
     9:         for _, v := range i {
    10:                 fmt.Println(v)
如果下次执行不希望有断点了,可以按clear 1,删除第一个断点也可以clearall删除全部断点,按b查看断点
(dlv) b
Breakpoint 5 set at 0x7ff948b60911 for :0
(dlv) clear 5
Breakpoint 5 cleared at 0x7ff948b60911 for :0
(dlv) clearall
Breakpoint 4 cleared at 0x0 for :0
Breakpoint 2 cleared at 0xf49812 for main.main() C:/Users/54225/AppData/Roaming/MobaXterm/home/project/learning/ch19/main.go:5