您现在的位置是:首页 >技术教程 >go调试工具-delve网站首页技术教程

go调试工具-delve

daliucheng 2024-08-11 00:01:03
简介go调试工具-delve

go调试工具-delve

简介

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

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

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

在这里插入图片描述

快速开始

安装

我本地的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
",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

在这里插入图片描述

输入help看帮助信息

断点

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

输入 b或者break

在这里插入图片描述

继续运行直到下一个断点

输入 c或者continue

在这里插入图片描述

逐步运行

输入n或者next

进入到调用函数(step in)

输入sstep

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

b main.go:17

在输入c

在这里插入图片描述

s进入,结果如下
在这里插入图片描述

查看当前执行的代码

list

在这里插入图片描述

退出当前函数(step out)

输入so或者step out

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

打印变量

p或者print

在这里插入图片描述

查看所有的本地变量

locals

在这里插入图片描述

重新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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ubRoJCwK-1685874754047)(C:UsersliuchenAppDataRoamingTypora	ypora-user-imagesimage-20230604164443208.png)]

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

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
    

在这里插入图片描述

  1. 选择的运行

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

    可以正常的做操作,比如打断点
    在这里插入图片描述

查看它支持的test相关的flag

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

 dlv test -- --test.cd

在这里插入图片描述

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中。

打断点

在这里插入图片描述

list查看代码

在这里插入图片描述

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

在这里插入图片描述

goLang操作

在这里插入图片描述

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

启动服务端

在这里插入图片描述

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

到这里就结束了

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。