安装delve

Devle是一个非常棒的golang 调试工具,支持多种调试方式,直接运行调试,或者attach到一个正在运行中的golang程序,进行调试。
线上golang服务出现问题时,Devle是必不少的在线调试工具,如果使用docker,也可以把Devle打进docker镜像里,调试代码。
在命令终端terminate中执行以下安装命令,进行delve的安装。
$ go get -u github.com/go-delve/delve/cmd/dlv

设置 launch.json 配置文件

command + shift + p 调出下拉列表,输入或者选择 Debug: Open launch.json,打开 launch.json 文件,如果第一次打开,会新建一个配置文件,默认配置内容如下

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

可能用到的属性介绍

启动配置必须具有的属性

每个启动配置都必须具有以下属性:
type - 用于此启动配置的调试器的类型,如python,go,Java等。每安装调试扩展引入一个类型:node用于内置节点调试器,例如,或php与go对PHP和去扩展。
request - 此启动配置的请求类型。目前,launch并且attach受到支持。
name - 阅读器友好名称,显示在“调试启动配置”下拉列表中。

可选属性

以下是可用于所有启动配置的一些可选属性:

preLaunchTask- 要在调试会话开始之前启动任务,请将此属性设置为tasks.json中指定的任务的名称(在工作空间的.vscode文件夹中)。
postDebugTask- 要在调试会话的最后启动任务,请将此属性设置为tasks.json中指定的任务的名称(在工作空间的.vscode文件夹中)。
internalConsoleOptions - 此属性控制调试会话期间“调试控制台”面板的可见性。
debugServer- 仅适用于调试扩展作者:此属性允许您连接到指定的端口,而不是启动调试适配器。

常用到的一些属性

许多调试器支持以下某些属性:

 program - 启动调试器时要运行的可执行文件或文件
 args - 传递给程序进行调试的参数
 env- 环境变量(该值null可用于“取消定义”变量)
 cwd - 当前工作目录,用于查找依赖项和其他文件
 port - 连接到正在运行的进程时的端口
 stopOnEntry - 程序启动时立即中断
 console-要使用什么样的主机,例如internalConsole,integratedTerminal或externalTerminal

常见属性如下

name	调试界面下拉选择项的名称(在最上面的DEBUG和设置按钮中间)
type	设置为go无需改动,是 vs code 用于计算调试代码需要用哪个扩展
mode	可以设置为 auto, debug, remote, test, exec 中的一个
program	调试程序的路径(绝对路径)
env	调试时使用的环境变量。例如:{ "ENVNAME": "ENVVALUE" , "go.gopath":"/Users/xx/go/src/xxx/项go项目名/cmd/http/main.go"},    // 调试时使用的环境变量。例如:{ "ENVNAME": "ENVVALUE" },gopath要指向本次要调试项目的主入口,即main.go所在的绝对路径
envFile	包含环境变量文件的绝对路径,在 env 中设置的属性会覆盖 envFile 中的配置
args	传给正在调试程序命令行参数数组
showLog	布尔值,是否将调试信息输出
logOutput	配置调试输出的组件(debugger, gdbwire, lldbout, debuglineerr, rpc),使用,分隔, showLog 设置为 true 时,此项配置生效
buildFlags	构建 go 程序时传给 go 编译器的标志
remotePath	远程调试程序的绝对路径,当 mode 设置为 remote 时有效
在 debug 配置中使用 VS Code 变量
${workspaceFolder} 调试 VS Code 打开工作空间的根目录下的所有文件
${file} 调试当前文件
${fileDirname} 调试当前文件所在目录下的所有文件
使用构建标记(build tags)
如果需要使用构建标记(e.g. go build -tags=whatever_tag)在参数 buildFlags 里写入 -tags=whatever_tag" 即可,支持多标签,使用单引号将标签包围,例如: "-tags='first_tag second_tag third_tag'"

debug 配置代码片段

可以在 launch.json 文件中,使用 Go 关键词调出 debug 配置项的代码片段。

调试当前文件配置片段

{
    "name": "Launch file",
    "type": "go",
    "request": "launch",
    "mode": "auto",
    "program": "${file}"
}

调试单个测试用例配置片段

{
    "name": "Launch test function",
    "type": "go",
    "request": "launch",
    "mode": "test",
    "program": "${workspaceFolder}",
    "args": [
        "-test.run",
        "MyTestFunction"
    ]
}

调试包中所有的测试用例配置片段

{
    "name": "Launch test package",
    "type": "go",
    "request": "launch",
    "mode": "test",
    "program": "${workspaceFolder}"
}

调试构建二进制文件配置片段

{
    "name": "Launch executable",
    "type": "go",
    "request": "launch",
    "mode": "exec",
    "program": "absolute-path-to-the-executable"
}

远程调试

远程调试需要在launch.json中将模式设置为远程"mode":“remote”,并且还需要服务器上起一个无头的 Delve 服务
例如:

$ dlv debug --headless --listen=:2345 --log --api-version=2

如果需要传参数到程序中,则需要将参数传入到 Delve 服务中
例如:

dlv debug --headless --listen=:2345 --log -- -myArg=123

launch.json 配置如下:

{
    "name": "Launch remote",
    "type": "go",
    "request": "launch",
    "mode": "remote",
    "remotePath": "服务器调试文件的目录(绝对路径)",
    "port": 2345,
    "host": "127.0.0.1",
    "program": "本地调试文件所在的目录(绝对路径)",
    "env": {}
}

将上述配置中的 host 和 port 修改 成Delve 服务所在的服务器ip和其监听的端口号。
remotePath 应该配置为调试文件的绝对路径
program 需要配置本地机器文件所在的绝对路径,是 remotePath 的一个副本
配置完成后,点击调试按钮,VS Code 将会向远程的 dlv 服务发出调试指令,而不是使用本机的 dlv 实例。

调试过程

在要进行调试的自定义函数或者自定义变量处,设置断点,断点的数目可以设置多个(注意,不要在开源的包中实现的方法处打断点,要不然调用栈会一直深入到开源实现的底层函数/变量处)。然后 Fn + F10(step over)进行单步调试(单步调试会跳过本次不执行的分支),左边栏中的VARIABLES变量中可以看到各个变量值的变化。如果想要进入到当前调试行中的函数里面,可以使用Fn + F11(step into)调入函数,不再想要执行函数内的语句,则可以 Fn + Shift+F11 (Step out ) 直接跳出当前函数,跳到上一次进入处的下一条语句。

注意:尽管在launch.json中定义了主函数main.go的绝对路径,但是在调试时,仍然想要先打开main.go程序,然后在启动调试Fn + F5后,跳转到要调试的程序处,接着可以选择单步调试Fn + F10或者进入函数Fn + F11,跳出函数Fn + shift + F11。通常,如果断点处又调用了其他自定义的函数,可以在分别在这个调用函数处和函数定义内部的其他函数调用/变量处打上多个断点,接着进行调试。

参考

https://code.visualstudio.com/Docs/editor/debugging
https://juejin.im/entry/5aa1f98d6fb9a028c522c84b
https://segmentfault.com/a/1190000018671207
https://github.com/Microsoft/vscode-go/wiki/Debugging-Go-code-using-VS-Code#sample-configuration-to-debug-a-single-test
https://github.com/go-delve/delve/tree/master/Documentation/installation

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐