Skip to content

在VS Code上调试golang项目

ozline edited this page Jun 8, 2023 · 3 revisions

前言

在开始之前,请先确保你的go版本不低于1.20

为了方便演示,我们使用ozline/grpc-todolist这个项目,这个项目有一个experimental的实验性模块

请先打开vscode,并且载入项目的工作文件夹

安装 Delve

Delve是专门针对go语言的调试器

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

创建 launch.json

  1. 我们打开vscode的命令窗口(默认快捷键是Ctrl/Command + Shift + P
  2. 输入Debug: Add Configuration,可以看见一个中文名为添加配置的选项,选择那个选项
  3. 选择调试器,选择Go
  4. 会再跳出来一个Choose debug configuration,选择第一个Go: Launch Package即可

接下来,你就会在根目录的.vscode/launch.json中看到下面这些内容

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Launch Package",
            "type": "go",
            "request": "launch",
            "mode": "auto",
            "program": "${fileDirname}"
        }
    ]
}

事实上,你也可以直接在根目录创建.vscode文件夹(注意是有点号的),然后在里面创建launch.json文件即可

编辑 launch.json

这里先拿grpc-todolist中的调试配置作为例子

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "exp-client",
            "type": "go",
            "request": "launch",
            "mode": "auto",
            "program": "${file}",
            "args": [
                "-config",
                "../../../config"
            ],
            "env": {
                "GRPC_GO_LOG_VERBOSITY_LEVEL": "99",
                "GRPC_GO_LOG_SEVERITY_LEVEL": "info",
            }
        },
        {
            "name": "exp-server",
            "type": "go",
            "request": "launch",
            "mode": "auto",
            "program": "${fileDirname}",
            "args": [
                "-config=../../config",
                "-srvnum=0",
            ],
            "env": {
                "GRPC_GO_LOG_VERBOSITY_LEVEL": "99",
                "GRPC_GO_LOG_SEVERITY_LEVEL": "info",
            }
        },
    ]
}

这里只列举一些关键的,其余的可以忽略

属性 介绍
name 这个调试项的名称
type vscode利用这个type判断该用什么来调试
mode 调试模式,除了上面的auto,还可以填写debug/remote等,一般auto
program ${file} 代表调试当前文件,${fileDirname}表示调试当前文件夹
args 调试时给程序传递的参数
env 调试时的环境变量

更多的属性及内容,可以参考文末的Reference

调试

环境准备

如果完成了上述内容,就可以开始进行调试了

我们先把目光放到./cmd/experimental/client中,这是一个为实验性模块随便写的一个简易的grpc客户端 我们先启动grpc的服务端

make env-up              # 启动项目环境
make experimental node=0 # 启动实验性模块的0号节点

因为实验性模块之前还用于测试负载均衡,所以通常都会带上node=x的参数,当然,你也可以不带,默认参数就是0

开始调试

回到vscode,打开./cmd/experimental/client/main.go,具体可以参考下面这个图(由于分辨率过高,看不清的话可以右键在新页面中查看图片) 调试基本界面

关注到里面的设置断点,我们设置好一个断点后,左侧的调试栏底下的断点就会多一个,我们可以在这里设置是否启用这个断点,也可以给这个断点设置表达式,只有满足表达式时这个断点才中断

比较灵活的是,vscode支持实时设置断点,也就是说你可以在程序运行过程中设置断点

调试控制

其实重点在于调试控制面板,从左到右依次如下

属性 介绍
继续 继续运行程序,一直运行到下一个断点,或者程序结束
单步跳过 程序继续运行一行代码
单步跳入 程序进入这个方法的实现,继续运行一行代码
单步跳出 程序跳出这个方法的实现,回到上一层,并继续运行一行代码(注意,这不是回到上一步,实际上相当于是执行完当前的方法,回到上一层,然后中断)
重启 重新启动程序
结束 结束调试

这里建议完成一次调试来体验这些功能,一般来说我们会使用继续来运行到下一个断点,使用单步跳过来实现一步一步的运行程序,使用单步跳入来进入这个方法,一步一步的完成这个方法。

我们为什么需要调试

如果你没有接到任务,你很难觉得调试是一件很重要的事,所以很多人会忽略掉调试

或者说,你其实也是在调试,只不过是人脑调试,比如我们有时候程序遇到bug,会在脑子里一步一步的模拟代码,然后推断程序运行到这里时某个变量应该是多少

但是你的脑子并不好使(bushi,你会出错,我们可以使用调试工具,可视化这一切过程,我们要在脑子里记得变量,会在界面中给你清晰的展示出来

例子

以本项目为例,假设我们现在想要知道一个unary请求是如何实现的。那么我们可以在请求开始的位置做一个断点

我们可以在client文件夹内的main.go中找到一个rpc.Ping()的方法,在这里设置一个断点,然后按照前面的方法开始跑调试(记得先开server端)

开始调试前,注意当前选中的文件应当是client文件夹内的main.go(或者把launch.json中的program改为这个文件的绝对地址)

调试开始后会在此处停下,然后你可以选择单步跳入进入这个方法的实现,探索具体的实现过程

Reference

  1. github - golang/vscode-go Debugging
  2. segmentfault - VS Code断点调试golang