go调试工具-delve

go调试工具-delve

简介

go debug工具,专门为go开发的调试工具,并且采用go语言开发,支持多平台。

官网:https://github.com/go-delve/delve

官网有详细的手册,学习起来很方便

go调试工具-delve_第1张图片

快速开始

安装

我本地的go版本
在这里插入图片描述

官方手册

go install github.com/go-delve/delve/cmd/dlv@latest

测试代码

package main

import (
	"context"
	"errors"
	"fmt"
)

func main() {
	fmt.Println("begin")

	var (
		a = []int{1,2,3,4,5}
		b = []int{1,2,3,4,5}
		ctx = context.Background()
	)
	res, err := doOperation(ctx, a, b)
	if err != nil {
		return
	}
	fmt.Printf("%v\n",res)

	fmt.Println("end")

}
func doOperation(ctx context.Context,a,b []int) ([]int,error)  {
	if len(a) == 0 && len(b) == 0{
		return nil,errors.New("slice is empty")
	}
	if len(a) != len(b){
		return nil,errors.New("slice length not equals")
	}
	res := make([]int, len(a))
	for index := range a {
		res[index] = a[index] + b[index]
	}
	return res,nil
}

文件结构

在这里插入图片描述

dlv开始调试

进入项目的根目录下,执行

dlv debug

go调试工具-delve_第2张图片

输入help看帮助信息

断点

在main.go的第十行打个断点

输入 b或者break

在这里插入图片描述

继续运行直到下一个断点

输入 c或者continue

go调试工具-delve_第3张图片

逐步运行

输入n或者next

进入到调用函数(step in)

输入sstep

现在在doOperation打个断点,先运行到这里

b main.go:17

在输入c

go调试工具-delve_第4张图片

s进入,结果如下
go调试工具-delve_第5张图片

查看当前执行的代码

list

go调试工具-delve_第6张图片

退出当前函数(step out)

输入so或者step out

现在运行到了doOperation,想要返回到main 调用它的地方,输入so

打印变量

p或者print

go调试工具-delve_第7张图片

查看所有的本地变量

locals

go调试工具-delve_第8张图片

重新debug

修改代码之后重新的debug

rebuild,会保留之前打的断点

使用介绍

上面的快速开始介绍了一些常用的使用方式,它的help写的很好,很清晰,关于单个命令就不再这里介绍了。

下面主要介绍几个命令

  1. debug
  2. exec
  3. test

除此之外还有一个子命令(开始dlv session之后的输入的命令)

disassemble-官方文档

debug

官方文档

dlv debug [package] [flags]

在没有参数的情况下,会自动编译当前文件夹下面的main包,也可以指定包的名字来debug

此外,还支持远程debug。

–headless :会开启一个服务端,用connect命令来连接及可进行debug,只要命令里面支持这个flag就可以用。

例子如下

  1. 启动服务端

    –headless:启动服务端

    -l:指定端口

    –log:开启日志

dlv debug --headless -l :2345 --log

在这里插入图片描述

  1. 客户端连接
dlv connect localhost:2345

go调试工具-delve_第9张图片

连接好之后就可以正常操作了。

exec

官方文档

对编译好的二进制进行debug

建议在build 二进制文件的时候要关闭掉编译器的优化,build的增加下面参数

-gcflags="all=-N -l"

同样的,它也支持服务器的方式,远程调试。

test

用来做单元测试的debug

官方文档

例子如下:

现在对上面的doOperation做单元测试,测试代码如下

package main

import (
	"context"
	"reflect"
	"testing"
)

func Test_doOperation(t *testing.T) {
	var ctx  = context.Background()
	t.Run("test1", func(t *testing.T) {
		type args struct {
			ctx context.Context
			a   []int
			b   []int
		}
		tests := []struct {
			name    string
			args    args
			want    []int
			wantErr bool
		}{
			{
				name:    "test1",
				args:    args{
					ctx: ctx,
					a:   []int{1,2,3,4},
					b:   []int{1,2,3,4},
				},
				want:    []int{2,4,6,8},
				wantErr: false,
			},
		}

		for _, tt := range tests {
			t.Run(tt.name, func(t *testing.T) {
				got, err := doOperation(tt.args.ctx, tt.args.a, tt.args.b)
				if (err != nil) != tt.wantErr {
					t.Errorf("doOperation() error = %v, wantErr %v", err, tt.wantErr)
					return
				}
				if !reflect.DeepEqual(got, tt.want) {
					t.Errorf("doOperation() got = %v, want %v", got, tt.want)
				}
			})
		}
	})
	t.Run("test2", func(t *testing.T) {
		type args struct {
			ctx context.Context
			a   []int
			b   []int
		}
		tests := []struct {
			name    string
			args    args
			want    []int
			wantErr bool
		}{
			{
				name:    "test1",
				args:    args{
					ctx: ctx,
					a:   []int{1,2,3,4},
					b:   []int{1,2,3,4},
				},
				want:    []int{2,4,6,8},
				wantErr: false,
			},
		}

		for _, tt := range tests {
			t.Run(tt.name, func(t *testing.T) {
				got, err := doOperation(tt.args.ctx, tt.args.a, tt.args.b)
				if (err != nil) != tt.wantErr {
					t.Errorf("doOperation() error = %v, wantErr %v", err, tt.wantErr)
					return
				}
				if !reflect.DeepEqual(got, tt.want) {
					t.Errorf("doOperation() got = %v, want %v", got, tt.want)
				}
			})
		}
	})
}

如上所示,一个方法里面有两个子测试。

dlv test [package] [flags]
  1. 运行当前package下所有的单测

    dlv test -- --test.v
    

go调试工具-delve_第10张图片

  1. 选择的运行

    dlv test -- --test.run Test_doOperation --test.v
    // 如果想要运行Test_doOperation中的test1,需要用/来拼接
    dlv test -- --test.run Test_doOperation/test1 --test.v
    

    可以正常的做操作,比如打断点
    go调试工具-delve_第11张图片

查看它支持的test相关的flag

随便输入一个错误的flag,会输出所有的flag

 dlv test -- --test.cd

go调试工具-delve_第12张图片

goLand 远程debug

这就是把上面说的远程debug和goLand结合了起来。先说出核心操作是

  1. 服务端开启用dlv 启动debug,headlress模式,go在build源码的时候需要禁用优化。
  2. 客户端连接,正常debug

先用命令行操作,在结合goLand使用

命令行操作

go build

go build -o debug_main  -gcflags "all=-N -l" base_go

dlv启动服务端

dlv exec ./debug_main --listen=:9987 --headless --api-version=2 --accept-multiclient --log
// 命令解释
// listen 指定host和port
// headless 启动无头浏览器
// api-version
// accept-multiclient

dlv启动客户端

 dlv connect hadoop105:9987

在这里插入图片描述

正常操作

现在的背景是:服务端在Linux服务器中,客户端在windows中。

打断点

go调试工具-delve_第13张图片

list查看代码

在这里插入图片描述

因为两个执行路径不一样,所以,打不开文件。但别的功能是可以用的,

go调试工具-delve_第14张图片

goLang操作

go调试工具-delve_第15张图片

搜索Go Remote,添加Host和Port,其实这里以及告诉我们服务端要怎么做了。

启动服务端

go调试工具-delve_第16张图片

先在config里面选择刚才的remote,打断点,debug运行(先打断点,在启动debug)

到这里就结束了

你可能感兴趣的:(go语言,golang,后端)