本文转载自微信公众号「脑子进煎鱼了」,作者陈煎鱼。转载本文请联系脑子进煎鱼了公众号。
创新互联专注于平山网站建设服务及定制,我们拥有丰富的企业做网站经验。 热诚为您提供平山营销型网站建设,平山网站制作、平山网页设计、平山网站官网定制、小程序开发服务,打造平山网络公司原创品牌,更为您提供平山网站排名全网营销落地服务。
大家好,我是煎鱼。
上一篇文章《一个 Demo 学会使用 Go Delve 调试》我们详细介绍了 Go 语言如何使用 Delve 进行排查和调试,对于问题的解决非常的有帮助。
但调试工具肯定不止只有 Delve,今天我们来介绍第二个神器,那就是:GDB,补全我们的调试工具技术栈。
根据小伙伴们的反馈,我们后面再增加 IDE 的调试篇章。
GDB 是一个类 UNIX 系统下的程序调试工具,允许你看到另一个程序在执行时 "内部 "发生了什么,或者程序在崩溃时正在做什么。
主要可以做四类事情:
如果是在 MacOS 上的话,可以直接使用 brew 安装:
- brew install gdb
如果是在 Linux ,则使用自带的包管理工具进行安装即可,但需要注意安装完毕后需要在 HOME 目录进行相关配置。
安装完毕后,执行 gdb 就可以看到:
- $ gdb
- GNU gdb (GDB) 10.2
- ...
- (gdb)
写此文时最新的 gdb 版本已经是 10.2 了,我也升级了上去。问题不大,还多了不少功能。
我们还是使用先前的演示程序来进行调试。但由于 Go 语言的不少编译优化,因此在编译运行程序时,有以下几点需要注意:
编译的命令是:
- $ go build -gcflags=all="-N -l" -ldflags='-compressdwarf=false' .
输出结果:
- !了鱼煎进子脑
GDB 有两种调试模式,分别是文本用户界面(Text User Interface,简称 tui)和默认的命令行模式:
- // 调试界面
- $ gdb -tui ./awesome-project
- // 命令行模式
- $ gdb ./awesome-project
接下来我们使用 gdb tui 的调试模式来给大家演示功能。
我们在执行命令 gdb -tui ./awesome-project 后,窗口会切换为如下:
gdb tui 初始样子
你会发现中间提示 “No Source Available”,此时你需要继续回车两次,他就会自动加载插件支持,提示:“Loading Go Runtime support.”。
我们就可以看到具体的代码块内容,如下:
用 MacOS 的同学需要注意,如果你在断点时发现发现了如下错误:
- (gdb) b main.main
- Breakpoint 1 at 0x10a2ea0: file /Users/eddycjy/go-application/awesomeProject/main.go, line 15.
- (gdb) r
- Starting program: /Users/eddycjy/go-application/awesomeProject/hello
- Unable to find Mach task port for process-id 64212: (os/kern) failure (0x5).
- (please check gdb is codesigned - see taskgated(8))
也就是 “please check gdb is codesigned - see taskgated(8)”,则需要重新处理证书认证和授权,是 MacOS 使用上的一个问题,具体可参考:《Codesign gdb on OSX》。
解决后,咱们的 gdb 就算是能够正确的运行起来了!
在 gdb 中,和 dlv 一样有常用的关键字命令。当然了,gdb 的 help all 输出非常多:
- (gdb) help all
- Command class: aliases
- Command class: breakpoints
- awatch -- Set a watchpoint for an expression.
- break, brea, bre, br, b -- Set breakpoint at specified location.
- break-range -- Set a breakpoint for an address range.
- catch -- Set catchpoints to catch events.
- ...
常用的关键字如下:
在调试上与 dlv 差不多,也是先执行关键字 b 打断点:
- (gdb) b main.main
- Breakpoint 1 at 0x10cbaa0: file /Users/eddycjy/go-application/awesomeProject/main.go, line 9.
也可以先执行关键字 l 查看对应的代码情况再进行做决定:
- (gdb) l main.main
- 4 "fmt"
- 5
- 6 "github.com/eddycjy/awesome-project/stringer"
- 7 )
- 8
- 9 func main() {
- 10 fmt.Println(stringer.Reverse("脑子进煎鱼了!"))
- 11 }
查看对应 goroutines 正在运行的函数情况:
- (gdb) info goroutines
- 1 waiting runtime.gosched
- * 13 running runtime.goexit
根据 pprof 等所得到的 goroutine 序号进行进一步的分析:
- (gdb) goroutine 1 bt
- #0 0x000000000040facb in runtime.gosched () at /home/user/go/src/runtime/proc.c:873
- #1 0x00000000004031c9 in runtime.chanrecv (c=void, ep=void, selected=void, received=void)
- at /home/user/go/src/runtime/chan.c:342
- #2 0x0000000000403299 in runtime.chanrecv1 (t=void, c=void) at/home/user/go/src/runtime/chan.c:423
- #3 0x000000000043075b in testing.RunTests (matchString...
注意一个细节,gdb 调试是可以看到并对 runtime 包内容的代码进行断点和分析的。
也可以和 dlv 一样执行 p 关键字输出相应的值的类型、值内容:
- (gdb) p re
- (gdb) p t
- $1 = (struct testing.T *) 0xf840688b60
- (gdb) p t
- $1 = (struct testing.T *) 0xf840688b60
- (gdb) p *t
- $2 = {errors = "", failed = false, ch = 0xf8406f5690}
- (gdb) p *t->ch
- $3 = struct hchan<*testing.T>
与 dlv 大同小异。
总体上来讲,MacOS 上使用 gdb 还是挺麻烦的,在 Linux 环境下使用 gdb 还是更方便些。
由于 dlv 和 gdb 在大致的调试上不会差距的太远,因此本文就没有过于展开。
若是对业务代码进行分析,更建议使用 dlv,也就是我们上一篇文章所讲的内容。若有 runtime 库的调试需求的话,推荐使用 gdb 来作为首要调试工具,若无这方面诉求,建议使用 dlv。
本文名称:学会使用GDB调试Go代码
文章转载:http://www.gawzjz.com/qtweb2/news47/8797.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联