Go代码调试工具 - delve

 

代码错误追踪是一件很头痛的事,使用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<workers; i++{
		go dostuff(&wg,i )
	}
	wg.Wait()
}

    程序中启用了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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值