目前 Go 语言支持 GDB、LLDB 和 Delve 几种调试器。其中 GDB 是最早支持的调试工具,LLDB 是 macOS 系统推荐的标准调试工具。但是 GDB 和 LLDB 对 Go 语言的专有特性都缺乏很大支持,而只有 Delve 是专门为 Go 语言设计开发的调试工具。而且 Delve 本身也是采用 Go 语言开发,对 Windows 平台也提供了一样的支持。本节我们基于 Delve 简单解释如何调试 Go 汇编程序。
安装
Github地址: https://github.com/go-delve/delve/
如果是在本地调试,直接通过go install命令将其安装到本地的$GOPATH/bin下即可
go install github.com/go-delve/delve/cmd/dlv@latest
容器环境下由于不一定支持 go,需要先安装 go 语言环境,会比较麻烦,可以直接将本地下载好的dlv二进制命令复制到$PATH的某一个目录中。安装好后,通过执行dlv version验证是否可用。
注意
使用go build编译时,默认会进行一些优化,会影响调试过程。
因此,对于对于需要进行调试的程序,在编译时最好设置-gcflags把优化关掉。
- 在>= 1.10的 golang 版本中,设置
-gcflags="all=-N -l" - 在<1.10版本的 golang 中,设置
-gcflags="-N -l"其中: -N表示不优化代码,并生成调试信息。-l表示禁用函数内联优化 如下面命令将当前文件夹下的代码编译成可执行文件main,并禁止优化:go build -gcflags="all=-N -l" -o main .## 基本使用 Delve 的基本命令: ``` (dlv) break main.main # 设置断点 (dlv) continue # 继续执行 (dlv) next # 下一步 (dlv) step # 步入 (dlv) print 变量名 # 打印变量
(dlv) b main.main # 在main函数设置断点 (dlv) bp 文件名:行号 # 在特定行设置断点 (dlv) c # continue 继续运行 (dlv) n # next 下一步 (dlv) s # step 步入 (dlv) p 变量名 # print 打印变量 (dlv) vars # 显示包级变量 (dlv) locals # 显示本地变量 (dlv) bt # 显示调用栈
## 常用命令
### `attach`
用于调试一个已经存在的进程,这个命令一般在调试 web 程序时使用。如下:
- 使用`lsof`命令查看占用某个端口的进程 pid
- 使用`dlv attach $pid`启动调试该进程
比如假定某个 web 程序的 http端口为 8080,进程号为10001
lsof -i:8080 dlv attach 10001
### `exec`
如果没有现成的进程,而只有一个二进制可执行文件,可以使用`dlv exec`命令启动一个进程并进行调试,如上面生成的`main`
dlv exec ./main
如果 main 程序本身需要一些参数,可以通过`--`来传递参数,比如给上面的 main 传入一个 conf 参数
dlv exec ./main -- conf=./conf.yaml
### `debug`
用于直接调试源码文件,这个命令连手动编译都省了,只需要指定调试的包名和源码所在的文件夹即可。
dlv debug .
dlv version