https://github.com/go-delve/delve
Devle是一个非常棒的golang 调试工具,支持多种调试方式,直接运行调试,或者attach到一个正在运行中的golang程序,进行调试。
线上golang服务出现问题时,Devle是必不少的在线调试工具,如果使用docker,也可以把Devle打进docker镜像里,调试代码。
安装Devle
安装Devle非常简单,直接运行go get 即可:
go get -u github.com/derekparker/delve/cmd/dlv
如果你的go版本为1.5请先设置环境变量GO15VENDOREXPERIMENT=1再运行go get。我的go版本为1.10,不用设置。
使用Devle调试golang服务
先写一个简单的web服务,然后使用Devle来进行调试。
在$GOPATH/src/github.com/mytest 文件夹下创建main.go
package main
import (
“fmt”
“log”
“net/http”
“os”
)
const port = “8000”
func main() {
http.HandleFunc(“/hi”, hi)
fmt.Println("runing on port: " + port)
log.Fatal(http.ListenAndServe(":" + port, nil)) }
func hi(w http.ResponseWriter, r *http.Request) {
hostName, _ := os.Hostname()
fmt.Fprintf(w, “HostName: %s”, hostName)
}
一个运行在8000端口上的web服务,访问 hi会返回机器的名称。上面代码的行号是很有用的,等会我们打断点的时候会用到。
使用Delve运行我们的main.go
dlv debug ./main.go
很简单的一些命令
我们先打在main方法上打一个断点:
b main.main
然后运行c 来运行到断点,
在func li 里打一个断点,我们可以使用
b main.hi
或者使用 “文件:行号”来打断点
b /home/goworkspace/src/github.com/mytest/main.go:20
现在执行continue 让服务跑起来。访问一下我们的服务,看hi方法会不会停下来。
curl localhost:8000/hi
输入 n 回车,执行到下一行
输入s 回车,单步执行
输入 print(别名p)输出变量信息
输入 args 打印出所有的方法参数信息
输入 locals 打印所有的本地变量
其他的命令我就不在这里给大家演示了,自己动动手试一下。
使用Delve附加到运行的golang服务进行调试
先编译一下我们的main.go然后去行main
go build main.go
./main
然后使用Delve附加到我们的项目上,先看一下我们的项目的pid
ps aux|grep main
dlv attach 29260
在hi方法里打断点,然后执行c来等待断点的执行。
b /home/goworkspace/src/github.com/mytest/main.go:20
访问我们的服务器,看一下断点会不会被执行
curl localhost:8000/hi
在windows系统下开发Linux环境下的分布式系统组件时,往往因为组件之间的相互依赖调用需要进行服务端调试,delve是一款开源的go语言调试器,常用的go语言IDE,如goland vscode等都是依靠delve来进行调试操作的.
使用goland远程调试
使用goland来进行远程调试最好使用goland的 2019.1版本,原因是在goland 2019.1之前的版本中,因为调试路径映射的问题,必需保证本地和远程代码目录都在GOPATH下的src目录,且文件夹必需同名才可以正常进行远程的断点调试,否则在本地ide开启远程调试后就会显示 error “could not find “
delve的issues里详细的说明了这个问题:https://github.com/go-delve/delve/issues/1163
将本地代码拷贝到远程调试机上,可以通过goland插件Remote Hosts Access来完成,也可以手动上传或者git clone
在远程调试机器上安装调试工具delve,安装方法 详见作者Github.
使用delve启动调试,这里有2中方式,一种是将代码手动编译成可执行程序调试,一种是直接使用dlv自动编译启动代码调试.
手动编译方式调试(使用了module特性的推荐使用此方式)
编译
go build -gcflags “all=-N -l” cmd/agent/main.go
go build -gcflags “all=-N -l” -o bin/agent -mod=vendor cmd/agent/main.go
go build -gcflags “-N -l” cmd/agent/main.go
运行
dlv –listen=:2345 –headless=true –api-version=2 exec bin/agent
1
直接debug自动编译运行
dlv debug –headless –listen=:2345 –api-version=2 cmd/agent/main.go
1
在本地goland添加远程调试配置
通过goland的菜单栏Run–>Edit Configurations来添加远程调试的配置
然后选择IDE右上角的远程调试选项,点击小虫子按钮开始远程调试就可以开心的在本地下断点远程调试服务端的程序啦!
tips
可以使用docker来降低调试环境复杂度,将dlv和go sdk封装到docker里面,挂载代码工程目录到docker里GOPATH下的src目录里.
拉取调试镜像
docker pull robolwq/golang-debug:1.10.3
1
挂载本地工程启动docker
docker container run -ti –rm –security-opt seccomp:unconfined –net=host -v /root/project:/root/go/src/project robolwq/golang-debug:1.10.3 bash
cd $GOPATH/src/project
dlv debug –headless –listen=:2345 –api-version=2 cmd/agent/main.go
如果使用goland 2019.1以下的版本则需要配置本地目录和远程目录都在环境变量GOPATH中,且相对路径一致
echo %GOPATH%
D:\workspace\go
echo $GOPATH
/root/go
cd /root/go/src/project
dlv debug –headless –listen=:2345 –api-version=2 cmd/agent/main.go
https://github.com/go-delve/delve/issues/1163
https://youtrack.jetbrains.com/issue/GO-3988
step1 远程主机
安装delve,项目地址:https://github.com/derekparker/delve
按照官方的提示安装即可(注意因为GFW等你懂得的原因,网络下载可能较慢或不可用,请自行使用某高科技软件,如ss+proxychains等工具)。
下载并安装完成后输入dlv就会看到帮助信息:
image.png
step2 本地
本地进入IDE,在要调试的地方打上断点,然后
run–debug–eidit configurations–>添加remote主机信息。
image.png
点debug 确认后,就会等待远端传回的debug信息。切远端:
step3 远端
如我要对 main.go 这个项目debug,对main进行编译后,可以直接运行
dlv –listen=:2345 –headless=true –api-version=2 exec ./main
然后本地就收到了调试信息。
https://davidlovezoe.wordpress.com/2019/01/24/golang-debug-intermediate/
https://baijiahao.baidu.com/s?id=1615101405775143768&wfr=spider&for=pc
https://github.com/go-delve/delve
在服务器上 ps x | grep game 查找到gameserver的进程pid |
然后服务器命令行输入:
dlv attach $PID –headless –api-version=2 –log –listen=:8181
本机只要输入:
dlv connect www.example.com:8181 连接到服务器上的dlv进程,就可以在本机远程调试了。
需要注意的是
本机quit 以后,远程dlv进程也会结束。
本机没有dlv connect,远程dlv直接关闭会导致 远程调试进程PID直接退出(很是忧伤)
本机dlv输入quit以后,会让你选择是否关闭调试进程,这个有时候也方便,不过大多数都是选择N 不关闭调试进程PID