golang debug 工具 dlv 可以非常方便 go 程序做单步调试。

安装

dlv工具安装:

$ git clone https://github.com/go-delve/delve
$ cd delve
$ go install github.com/go-delve/delve/cmd/dlv

使用

三种用法,

直接在代码目录下运行main文件:

$ dlv debug

直接 attach 已经运行的目标程序

$ dlv attach <PID>

运行二进制程序:

$ dlv exec <目标二进制程序>

案例

package main

import (  
    "fmt"
    "time"
)

func main() {  
    arr := []int{101, 95, 10, 188, 100}
    max := arr[0]
    for _, v := range arr {
        if v > max {
            max = v
        }
    }
    fmt.Printf("Max element is %d\n", max)
    var s string
    for {
      t1 := time.Now()
      fmt.Scan(&s)
      t2 := time.Now()
      if s == "q"{
        break
      }
      fmt.Println(t2.Sub(t1).Seconds())
    }
}

先启动 debug 模式, debug命令会在程序启动就设置一个断点:

$ dlv debug main.go

# 在main.go文件第10行设置断点
(dlv) break main.go:10 
Breakpoint 1 set at 0x4acda4 for main.main() ./main.go:10

# 让程序继续执行到下个断点位置
(dlv) continue
> main.main() ./main.go:10 (hits goroutine(1):1 total:1) (PC: 0x4acda4)
     5:	    "time"
     6:	)
     7:	
     8:	func main() {  
     9:	    arr := []int{101, 95, 10, 188, 100}
=>  10:	    max := arr[0]
    11:	    for _, v := range arr {
    12:	        if v > max {
    13:	            max = v
    14:	        }
    15:	    }

# 查看当前调用栈
(dlv) stack 
0  0x00000000004acda4 in main.main
   at ./main.go:10
1  0x0000000000435333 in runtime.main
   at /root/go/src/runtime/proc.go:255
2  0x000000000045fca1 in runtime.goexit
   at /root/go/src/runtime/asm_amd64.s:1581

# 在当前文件第16行设置断点
(dlv) break 16 
Breakpoint 2 set at 0x4ace45 for main.main() ./main.go:16

# 断点执行到下一行代码
(dlv) next

# 打印arr变量
(dlv) print max
101
# 修改max变量,这里修改变量只能修改数字或指针,因为这里本质是修改程序内存空间
(dlv) set max = 333
(dlv) print max
333
# 让程序继续执行到下个断点位置
(dlv) continue 
> main.main() ./main.go:16 (hits goroutine(1):1 total:1) (PC: 0x4ace45)
    11:	    for _, v := range arr {
    12:	        if v > max {
    13:	            max = v
    14:	        }
    15:	    }
=>  16:	    fmt.Printf("Max element is %d\n", max)
    17:	    var s string
    18:	    for {
    19:	      t1 := time.Now()
    20:	      fmt.Scan(&s)
    21:	      t2 := time.Now()
# next 我们可以看到打印出来的最大值是333了
(dlv) next
Max element is 333