Go代码调试工具 - delve

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

 

代码错误追踪是一件很头痛的事,使用delve debug工具可以轻松完成对go程序的调试。

安装

此处介绍Linux上的安装,其他的大同小异, 

第一种方式是用go get获取。

go get -u github.com/derekparker/delve/cmd/dlv

第二种是使用源码安装:

$ git clone https://github.com/derekparker/delve.git $GOPATH/src/github.com/derekparker/delve
$ cd $GOPATH/src/github.com/derekparker/delve
$ make install

但是必须确认设置了GOPATH环境变量,

还要注意的事:如果您使用的是GO 1.5,则必须在继续之前设置GO15VANDORAMED=1

安装中的问题:

1.  环境变量GOARCH

github.com\derekparker\delve\proc\disasm.go:9: undefined: ArchInst

    这个问题就是因为没有设置go的环境变量GOARCH为操作系统或者go安装时的位数( 386 / amd64 ),根据自己环境设置。

2.  Linux( Ubuntu) 不允许不同用户attach ID连接程序进行调试

Could not attach to process.  If your uid matches the uid of the target process, check the setting of /proc/sys/kernel/yama/ptrace_scope, or try again as the root user.  For more details, see /etc/sysctl.d/10-ptrace.conf

       将此文件下的kernel.yama.ptrace_scope = 1 改为0, 允许普通用户调试。但必须重启生效。

 

调试代码

示例代码:

package main

import(
	"fmt"
	"sync"
	"time"
)

func dostuff(wg *sync.WaitGroup , i int){
	fmt.Printf("groutime id %d \n", i)
	time.Sleep(300*time.Second)	
	fmt.Printf("goroutine id %d\n", i)
	wg.Done()
}
func main(){
	var wg sync.WaitGroup
	workers := 10

	wg.Add(workers)
	for i:=0; i

    程序中启用了10个goroutine来分别往控制台输出, 下面使用delve来调试程序:

dlv debug delve.go

    运行这个命令,dlv会去编译你的代码,然后传一些参数给编译器,好让编译器编译出来更加方便调试的可执行文件,然后启动了你的程序,并且attach上去,这样你的console就会停留在了debug session,下面就可以调试程序了。

那么,我们先在main函数上设置一个断点。

(dlv) break main.main
Breakpoint 1 set at 0x22d3 for main.main() ./test-debug.go:16

        输出信息里面告诉了我们断点的 ID和断点的位置,函数名和文件名以及所在行数。我们使用continue命令让程序运行到我们打断点的地方。

(dlv) continue
> main.main() ./test-debug.go:16 (hits goroutine(1):1 total:1) (PC: 0x22d3)
    11:        time.Sleep(300 * time.Second)
    12:        fmt.Printf("goroutine id %d\n", i)
    13:        wg.Done()
    14:    }
    15:
=>  16:    func main() {
    17:        var wg sync.WaitGroup
    18:        workers := 10
    19:
    20:        wg.Add(workers)
    21:        for i := 0; i < workers; i++ {
(dlv)

        现在程序就停在了第一个断点,现在我们可以使用next命令让程序运行到下一句话,如果你想继续向下,可以直接按回车(如果你按下回车键,Delve会重复上一条命令)。

(dlv) next
> main.main() ./test-debug.go:17 (PC: 0x22d7)
    12:        fmt.Printf("goroutine id %d\n", i)
    13:        wg.Done()
    14:    }
    15:
    16:    func main() {
=>  17:        var wg sync.WaitGroup
    18:        workers := 10
    19:
    20:        wg.Add(workers)
    21:        for i := 0; i < workers; i++ {
    22:            go dostuff(&wg, i)
(dlv)
> main.main() ./test-debug.go:18 (PC: 0x22f1)
    13:        wg.Done()
    14:    }
    15:
    16:    func main() {
    17:        var wg sync.WaitGroup
=>  18:        workers := 10
    19:
    20:        wg.Add(workers)
    21:        for i := 0; i < workers; i++ {
    22:            go dostuff(&wg, i)
    23:        }
(dlv)
> main.main() ./test-debug.go:20 (PC: 0x22fa)
    15:
    16:    func main() {
    17:        var wg sync.WaitGroup
    18:        workers := 10
    19:
=>  20:        wg.Add(workers)
    21:        for i := 0; i < workers; i++ {
    22:            go dostuff(&wg, i)
    23:        }
    24:        wg.Wait()
    25:    }
(dlv)    

现在我们可以尝试使用print命令去看一下变量的值。

(dlv) print wg
sync.WaitGroup {
    state1: [12]uint8 [0,0,0,0,0,0,0,0,0,0,0,0],
    sema: 0,}
(dlv) print workers
10
(dlv)

同时你也可以输出一个表达式

(dlv) print workers < 100
true

简洁的命令

1. 指定行号设置断点:


(dlv) b main.go:16 #在 main.go 的第 16 行设置断点。

2. 查看所有断点


(dlv) bp   #查看当前所有断点

3.  运行至下一个断点

(dlv) c    #运行到下一个断点或者到程序结尾

4. 打印变量


(dlv) p a  #打印变量 a 的值 ( 此变量必须是程序中声明的)

5. 单步执行代码

(dlv) n    #单步执行代码

6.  手动修改变量值

(dlv) set a=1  #设置变量a 的值(变量在程序中存在)

命令大全

命令 描述
args 打印函数参数
break 设置一个断点
breakpoints 打印激活的断点信息
clear 删除断点
clearall 删除所有的断点
condition 设置断点条件
continue 运行到断点或程序终止
disassemble 拆解器
exit 退出debugger
frame 在不同的框架上执行的命令
funcs 打印函数列表
goroutine 显示或更改当前goroutine
goroutines 列出程序的全部goroutines
help 打印出帮助信息
list 显示源代码
locals 打印局部变量
next 跳到下一行
on 在遇到断点时执行一个命令
print 评估表达式
regs 打印CPU寄存器的内容
restart 重启进程
set 更改变量的值
source 执行包含delve命令列表的文件
sources 打印源文件列表
stack 打印堆栈跟踪
step 单步执行程序
step-instruction 单步单个执行cpu指令
thread 切换到指定的线程
threads 打印每一个跟踪线程的信息
trace 设置跟踪点
types 打印类型列表
vars 打印某个包内的(全局)变量

 

Delve 命令详解

我们在命令行中输入dlv, 会看到:

Delve is a source level debugger for Go programs.

Delve enables you to interact with your program by controlling the execution of the process,
evaluating variables, and providing information of thread / goroutine state, CPU register state and more.

The goal of this tool is to provide a simple yet powerful interface for debugging Go programs.

Pass flags to the program you are debugging using `--`, for example:

`dlv exec ./hello -- server --config conf/config.toml`

使用方式

Usage: 
  dlv [command]

 

可用的命令

Available Commands:
  attach      关联到一个已经运行的程序上进行调试.

        dlv attach  [程序的PID]
  connect     Connect to a headless debug server.
  core        Examine a core dump.
  debug       Compile and begin debugging main package in current directory, or the package specified.
  exec        Execute a precompiled binary, and begin a debug session.
  help        Help about any command
  run         Deprecated command. Use 'debug' instead.
  test        Compile test binary and begin debugging program.
  trace       Compile and begin tracing program.
  version     Prints version.

 

为调试附加的参数

Flags: 
      --accept-multiclient   Allows a headless server to accept multiple client connections. Note that the server API is not reentrant and clients will have to coordinate.
      --api-version int      Selects API version when headless. (default 1)
      --backend string       Backend selection:

部分为列出...

 

 

 

未完待续.....

 

转载于:https://my.oschina.net/90design/blog/1843762

你可能感兴趣的:(Go代码调试工具 - delve)