当线上或其它非本地环境遇到问题无法本地复现时,往往需要远程调试,在服务端运行服务,本地使用 IDE 进行调试,本文介绍在 IDEA 使用 Delve 做远程调试,虽然 IDEA Go Remote 有比较清楚说明,但使用中还是有几点需要注意。

Go Remote

首先在 IDEA 的 Run/Debug Configurations 选择添加 Go Remote,Host填主机 IP,Port可以默认不变,同时窗口中有以下说明:

Before running this configuration, please start your application and Delve as described bellow.  Allow Delve to compile your application: 
dlv debug --headless --listen=:2345 --api-version=2 --accept-multiclient
 
Or compile the application using one of these commands: 
go build -gcflags "all=-N -l" github.com/app/demo
for Go 1.10 or later
 
go build -gcflags "-N -l" github.com/app/demo
for Go 1.9 or earlier
 
and then run it via Delve with the following command:
dlv --listen=:2345 --headless=true --api-version=2 --accept-multiclient exec ./demo

基本了解后开始介绍具体使用流程,此时可以把 Host 填好并 Apply

Delve 安装

根据环境分别在服务端和本地安装dlv工具,Installation

编译

使用go build -gcflags "all=-N -l" github.com/app/demo编译,以hb-chen/gateway为例:

cd $GOPATH/src/github.com/hb-chen/gateway

# 编译 linux
GOOS=linux go build -gcflags "all=-N -l" cmd/main.go

上传执行文件服务端

scp main root@{HOST_IP}:/workdir/

Delve 运行服务

接下来在服务端运行服务,这时有个问题,命令行参数怎么添加?答案是需要使用--与 Delve 运行命令分隔开,如gateway示例添加-e参数使用标准输出打印日志,命令如下:

# 无参数
dlv --listen=:2345 --headless=true --api-version=2 --accept-multiclient exec ./main

# -- 为分隔符
# -e 为参数
dlv --listen=:2345 --headless=true --api-version=2 --accept-multiclient exec ./main -- -e

调试

此时回到 IDEA 启动 Debug 就可以远程调试了

调试时如果需要修改gateway的启动参数,又会遇到另一个问题,在服务端的终端ctl + c无法退出,这时需要使用本地安装的dlv工具连接到服务端,然后执行exit会询问Would you like to kill the headless instance? [Y/n]选择Y,此时服务端终端退出,再重新启动。

dlv connect {HOST_IP}:2345

Type 'help' for list of commands.
(dlv) exit
Would you like to kill the headless instance? [Y/n] Y