Go Lang远程调试 with Goland

8,033 阅读1分钟

GO语言远程调试

如果想直接使用goland进行调试请直接跳到第2节。
远程调试还是很常用的,就像java中jdwp那样,remote debug,有些bug不方便复线,直接在测试服上面debug很容易确定问题。

1.Delve工具的使用

Delve是一个为go语言提供的调试器。目的提供给go语言一个全功能的简化的调试工具,Delve工具github地址

安装Delve

  1. 从github资源库下载并安装
$ git clone https://github.com/go-delve/delve
$ cd delve
$ go install github.com/go-delve/delve/cmd/dlv
  1. go版本>1.16简化如下(升级golang version可以参考我的另一篇博文)
$ go install github.com/go-delve/delve/cmd/dlv@latest

如果都不行,那你要考虑一下你上网是不是科学。go这个东西劝退好多原因都是在这里。

  1. 尝试一下dlv命令,他一般会安装在$GOPATH目录下,如果command not found,你要把这个目录/bin放到你的环境变量里面。

命令行使用Delve 进行Debug

比如我的项目目录结构是这样的: 项目路径中有一个main包,main包下面是main函数,
那么使用dlv的debug命令即可启动mian函数开始debug执行。注意其中--后面的参数是我的main需要的参数,不是dlv的参数。

dlv debug ./main/main.go -- -env=debug -service=agent,debug,game,login,admin,msgq

然后, 其中 (dlv)类似于命令提示符,break main.mian是对main包的main函数打断点,可以打多个断点,具体的命令参考 dlv客户端的命令

(dlv) break main.main
Breakpoint 1 set at 0x20e06f3 for main.main() ./main/main.go:68

然后使用continue命令,让程序继续执行,直到遇到断点会停下。如图吧。

image.png 然后使用 next命令和step命令等执行单步调试,使用args和display命令来显示调试数值。如图:

image.png

用命令行来调试实在是太反人类了,还是使用ide吧。 接下来我们使用GOLang来远程调试吧。

2 使用GoLand配合Delve 进行远程调试

前面我们已经了解了命令行的方式调试,实在是太反人类了。现在我们用Delve支持的客户端来调试,这里我们使用GOLang来作。
还有更多的文本编辑器或插件支持了del的远程调试,见列表

使用Golang远程调试

1.安装Delve

这里是在远程机器上安装,方式和上面1.1中讲的内容一致。注意是remote上安装,也就是你想远程调试的那个机器。

2.启动远程代码

注意,这里,使用 dlv的exec命令来启动你的远程代码,其中下面的exec后面的./ascension是我的程序,-- 后面的是我自己的程序需要的参数。前面是dlv的参数,监听在2345端口,不需要命令提示头(dlv)等等。

dlv --listen=:2345 --headless=true --api-version=2 --accept-multiclient exec ./ascension -- -env=test -service=login,msgq,game,fusion,agent,debug

远程构建的应用进程,需要禁止掉编译优化,如下,需要build的时候填加如下参数:

go build -gcflags \"all=-N -l\" -o ./build/ascension ./main/main.go

启动界面如图,程序会阻塞等待goland的连接: image.png

3.GoLand配置一下就好了

首先打开debug config界面,点+号,点Go Remote按钮,如图:

image.png

然后填上刚才启动app目标服的ip和端口
我这里是5432端口,首先要确定服务器端口可用,可以先telnet nc之类的确定通了再配置:

image.png

然后启动选择remote你刚添加这个就可以愉快的debud remote的代码啦!

4. 遇到的问题 去掉dlv阻塞

  1. 我不想要remote程序阻塞等我debug,而是直接执行,那么可以在启动远程程序的时候添加 --continue参数。
  2. 我不想每次都重启远程服务器,那么就直接写到启动脚本中用dlv启动,测试环境
  3. debug中没有ctrl+c 和退出的q命令,需要直接kill掉进程 代码如下吧,能理解第二行就行。
function start() {
  dlv --listen=:5432 --headless=true --api-version=2 --continue --accept-multiclient exec ./ascension -- -env=test -service=login,msgq,game,fusion,agent,debug >./logs/stdout 2>./logs/stderr &
  pid=$!
  echo "$pid" > ./boot.pid
  echo "go boot ${jarfile} Process Id:$pid begin running!"
}

3.后续问题