Ubuntu 系统安装 go 调试工具 delve
安装 go
1. 下载 go 二进制
- 这里选择安装 go 1.14.1 版本,直接下载官方的二进制,解压后直接就可以用,非常方便,下载链接为
go1.14.1.linux-amd64.tar.gz:
https://golang.google.cn/dl/go1.14.1.linux-amd64.tar.gz
tar -zxvf go1.14.1.linux-amd64.tar.gz
- 解压后会出现一个 go 目录,进入 go/bin 目录下,会看到二进制文件,可以运行查看下版本:
lhx@lhx-ubuntu:~/go/bin$ ls
go gofmt
lhx@lhx-ubuntu:~/go/bin$ ./go version
go version go1.14.1 linux/amd64
2. 配置 go 环境变量
-
添加 go 到 PATH 变量
export PATH=/home/lhx/go/bin:$PATH
-
设置 GOPATH(不能和GOROOT路径一致)
export GOPATH=/home/lhx/gopath
- 通过命令
go env
可以查看变量:
GOPATH="/home/lhx/gopath"
GOROOT="/home/lhx/go"
安装 delve
1. 下载 delve 源码
- 从 github 下载源码
git clone https://github.com/go-delve/delve.git $GOPATH/src/github.com/go-delve/delve
- 网速慢的话,可以从 gitcode 镜像下载:
git clone https://gitcode.net/mirrors/derekparker/delve.git $GOPATH/src/github.com/go-delve/delve
2. 安装 delve
- 进入 delve 目录,通过命令
make install
安装。 - 由于 golang.org 被墙了,可能会报错:
lhx@ubuntu:~/gopath/src/github.com/go-delve/delve$ make install
go: github.com/cosiner/argv@v0.0.0-20170225145430-13bacc38a0a5: Get "https://proxy.golang.org/github.com/cosiner/argv/@v/v0.0.0-20170225145430-13bacc38a0a5.mod": dial tcp 172.217.160.113:443: connect: connection refused
make: *** [Makefile:10:install] 错误 1
- 解决方法:改成中国的 Go 模块代理,在终端执行:
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct
- 可以通过
go env
再查看 GOPROXY 变量。 - 此时
make install
就成功了:
lhx@lhx-ubuntu:~/gopath/src/github.com/go-delve/delve$ make install
go: downloading github.com/spf13/cobra v0.0.0-20170417170307-b6cb39589372
go: downloading github.com/spf13/pflag v0.0.0-20170417173400-9e4c21054fa1
go install "-ldflags=-X main.Build=237c5026f40e38d2dd6f62a7362de7b25b00c1c7" github.com/go-delve/delve/cmd/dlv
go: downloading github.com/sirupsen/logrus v1.6.0
go: downloading github.com/cpuguy83/go-md2man v1.0.10
go: downloading gopkg.in/yaml.v2 v2.2.1
go: downloading github.com/peterh/liner v0.0.0-20170317030525-88609521dc4b
go: downloading github.com/cosiner/argv v0.0.0-20170225145430-13bacc38a0a5
go: downloading go.starlark.net v0.0.0-20190702223751-32f345186213
go: downloading golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb
go: downloading github.com/google/go-dap v0.2.0
go: downloading github.com/mattn/go-isatty v0.0.3
go: downloading golang.org/x/arch v0.0.0-20190927153633-4e8777c89be4
go: downloading github.com/russross/blackfriday v1.5.2
go: downloading github.com/hashicorp/golang-lru v0.5.4
- 安装成功后,可以进入到 GOPATH,会发现有 bin 目录,里面有 dlv 二进制文件,可以运行查看 delve 版本号:
lhx@lhx-ubuntu:~/gopath/src/github.com/go-delve/delve$ cd $GOPATH
lhx@lhx-ubuntu:~/gopath$ ls
bin pkg src
lhx@lhx-ubuntu:~/gopath$ cd bin/
lhx@lhx-ubuntu:~/gopath/bin$ ls
dlv
lhx@lhx-ubuntu:~/gopath/bin$ ./dlv version
Delve Debugger
Version: 1.4.0
Build: 237c5026f40e38d2dd6f62a7362de7b25b00c1c7
- 添加$GOPATH/bin到环境变量,即可在任意位置执行 dlv 命令:
export PATH=/home/lhx/gopath/bin:PATH
3. 测试 delve
- 写一个简单的 hello word 程序测试,命名为 main.go :
package main
import "fmt"
func main() {
fmt.Println("hello world")
}
- 开始调试:
lhx@lhx-ubuntu:~/gopath/bin$ ./dlv debug main.go
Type 'help' for list of commands.
(dlv)
- 通过命令
help
查看帮助信息:
(dlv) help
The following commands are available:
Running the program:
call ------------------------ Resumes process, injecting a function call (EXPERIMENTAL!!!)
continue (alias: c) --------- Run until breakpoint or program termination.
next (alias: n) ------------- Step over to next source line.
restart (alias: r) ---------- Restart process.
step (alias: s) ------------- Single step through program.
step-instruction (alias: si) Single step a single cpu instruction.
stepout (alias: so) --------- Step out of the current function.
Manipulating breakpoints:
break (alias: b) ------- Sets a breakpoint.
breakpoints (alias: bp) Print out info for active breakpoints.
clear ------------------ Deletes breakpoint.
clearall --------------- Deletes multiple breakpoints.
condition (alias: cond) Set breakpoint condition.
on --------------------- Executes a command when a breakpoint is hit.
trace (alias: t) ------- Set tracepoint.
Viewing program variables and memory:
args ----------------- Print function arguments.
display -------------- Print value of an expression every time the program stops.
examinemem (alias: x) Examine memory:
locals --------------- Print local variables.
print (alias: p) ----- Evaluate an expression.
regs ----------------- Print contents of CPU registers.
set ------------------ Changes the value of a variable.
vars ----------------- Print package variables.
whatis --------------- Prints type of an expression.
Listing and switching between threads and goroutines:
goroutine (alias: gr) -- Shows or changes current goroutine
goroutines (alias: grs) List program goroutines.
thread (alias: tr) ----- Switch to the specified thread.
threads ---------------- Print out info for every traced thread.
Viewing the call stack and selecting frames:
deferred --------- Executes command in the context of a deferred call.
down ------------- Move the current frame down.
frame ------------ Set the current frame, or execute command on a different frame.
stack (alias: bt) Print stack trace.
up --------------- Move the current frame up.
Other commands:
config --------------------- Changes configuration parameters.
disassemble (alias: disass) Disassembler.
edit (alias: ed) ----------- Open where you are in $DELVE_EDITOR or $EDITOR
exit (alias: quit | q) ----- Exit the debugger.
funcs ---------------------- Print list of functions.
help (alias: h) ------------ Prints the help message.
libraries ------------------ List loaded dynamic libraries
list (alias: ls | l) ------- Show source code.
source --------------------- Executes a file containing a list of delve commands
sources -------------------- Print list of source files.
types ---------------------- Print list of types
Type help followed by a command for full documentation.
- 设置 main 函数断点,继续 c、下一步 n、退出 q:
(dlv) break main.main
Breakpoint 1 set at 0x4adb8f for main.main() ./main.go:5
(dlv) c
> main.main() ./main.go:5 (hits goroutine(1):1 total:1) (PC: 0x4adb8f)
1: package main
2:
3: import "fmt"
4:
=> 5: func main() {
6: fmt.Println("hello world")
7: }
8:
(dlv) n
> main.main() ./main.go:6 (PC: 0x4adb9d)
1: package main
2:
3: import "fmt"
4:
5: func main() {
=> 6: fmt.Println("hello world")
7: }
8:
(dlv) n
hello world
> main.main() ./main.go:7 (PC: 0x4adbff)
2:
3: import "fmt"
4:
5: func main() {
6: fmt.Println("hello world")
=> 7: }
8:
(dlv) c
Process 24972 has exited with status 0
(dlv) q