30. 如何使用 GDB 调试 Go 程序?
Hi,大家好,我是明哥。
在自己学习 Golang 的这段时间里,我写了详细的学习笔记放在我的个人微信公众号 《Go编程时光》,对于 Go 语言,我也算是个初学者,因此写的东西应该会比较适合刚接触的同学,如果你也是刚学习 Go 语言,不防关注一下,一起学习,一起成长。
我的在线博客: http://golang.iswbm.com
我的 Github:github.com/iswbm/GolangCodingTime
做为新手,熟练掌握一个好的调试工具,对于我们学习语言或者排查问题的时候,非常有帮助。
你如果使用 VS Code 或者 Goland ,可以直接上手,我就不再写这方面的文章了。
其实相比有用户界面的 IDE 调试工具,我更喜欢简单直接的命令行调试,原因有三点:
- 速度快,个人感觉在 Windows 下速度巨慢
- 依赖少,在 Linux 服务器上 也能轻松调试
- 指令简单,我习惯只使用快捷键就能操作
如果你有和我一样的感受和习惯,可以看下今天的文章,介绍的是 GDB 调试工具。
1. 下载安装 Go
在 Linux 上进行调试,那咱所以得先安装 Go ,由于第一节里只讲了 Windows 的下载安装,并没有讲到在 Linux 上如何安装。所以这里要先讲一下,已经安装过了可以直接跳过。
首先在 go 下载页面上( https://golang.org/dl/ ),查看并复制源码包的的下载地址
登陆 linux 机器 ,使用 wget 下载
$ wget https://dl.google.com/go/go1.14.2.linux-amd64.tar.gz
将下载的源码包解压到 /usr/local
目录下,并设置环境变量
[root@localhost ~]# tar -C /usr/local -xzf go1.14.2.linux-amd64.tar.gz [root@localhost ~]# [root@localhost ~]# export PATH=$PATH:/usr/local/go/bin [root@localhost ~]# which go /usr/local/go/bin/go [root@localhost ~]# [root@localhost ~]# go version go version go1.14.2 linux/amd64 [root@localhost ~]#
2. 开始进行调试
调试使用的是 GDB (好像要求版本 7.1 + ),使用前,请先确保你的机器上已经安装 GDB
[root@localhost code]# which gdb /usr/bin/gdb
准备就绪后,先在目录下写一个测试文件
package main import "fmt" func main(){ msg := "hello, world" fmt.Println(msg) }
然后执行 如下命令进行编译,里面有好多个参数,有疑问的可以自行搜索引擎
# 关闭内联优化,方便调试 $ go build -gcflags "-N -l" demo.go # 发布版本删除调试符号 go build -ldflags “-s -w”
最后使用 GDB 命令进入调试界面
# 如果你喜欢这种界面的话,用这条命令 $ gdb -tui demo # 如果你跟我一样不喜欢不习惯用界面,就使用这个命令 $ gdb demo
完整操作如下:
进入 GDB 调试界面后,并不是立即可用,你先需要回车,然后再你敲入几行命令,调试窗口就会出现代码。
(gdb) b main.main # 在 main 包里的 main 函数 加断点 Breakpoint 1 at 0x4915c0: file /home/wangbm/code/demo.go, line 5. (gdb) run # 执行进程 Starting program: /home/wangbm/code/demo Breakpoint 1, main.main () at /home/wangbm/code/demo.go:5 (gdb)
3. 详解调试指令
要熟练使用 GDB ,你得熟悉的掌握它的指令,这里列举一下
r n s b l c bt p q whatis info breakpoints info locals info args info frame info goroutines goroutine 1 bt
其中有几个指令的使用比较灵活
比如 l – list,查看代码
# 查看指定行数上下5行 (gdb) l 8 # 查看指定范围的行数 (gdb) l 5:8 # 查看指定文件的行数上下5行 l demo.go:8 # 可以查看函数,记得加包名 l main.main
把上面的 l
换成 b
,大多数也同样适用
# 在指定行打断点 (gdb) b 8 # 在指定指定文件的行打断点 b demo.go:8 # 在指定函数打断点,记得加包名 b main.main
还有 p – print,打印变量
# 查看变量 (gdb) p var # 查看对象长度或容量 (gdb) p $len(var) (gdb) p $cap(var) # 查看对象的动态类型 (gdb) p $dtype(var) (gdb) iface var # 举例如下 (gdb) p i $4 = {str = "cbb"} (gdb) whatis i type = regexp.input (gdb) p $dtype(i) $26 = (struct regexp.inputBytes *) 0xf8400b4930 (gdb) iface i regexp.input: struct regexp.inputBytes *
以上就是关于 GDB 的使用方法,非常简单,可以自己手动敲下体验一下。
参考文章
系列导读
24. 超详细解读 Go Modules 前世今生及入门使用
欢迎关注我们的微信公众号,每天学习Go知识