当前位置: 首页 > 科技观察

Go语言源码级调试器Delve

时间:2023-03-18 12:26:47 科技观察

01简介Delve是一款简单、强大、易用的Go语言源码级调试器,也是Go官方推荐的调试器。02安装Delve安装非常简单。如果读者使用的是Go1.16或更高版本,可以直接使用goinstall安装:goinstallgithub.com/go-delve/delve/cmd/dlv@latest如果读者使用的是低于Go1.16的版本,但首先下载Delve源码,然后使用goinstall安装:gitclonehttps://github.com/go-delve/delvecddelvegoinstallgithub.com/go-delve/delve/cmd/dlv安装完成后,可以使用gohelpinstall查看dlv可执行文件的详细位置。建议读者将dlv可执行文件配置到PATH环境变量中。需要注意的是,如果读者使用的是macOS,还需要安装命令行开发工具:xcode-select--install为了避免每次使用dlv都需要授权使用debugger,推荐读者开启开发者模式:sudo/usr/sbin/DevToolsSecurity-enable03练习完成Part02的所有操作后,我们使用dlvversion检查dlv可执行程序是否可以使用。我们可以使用dlv的任何可用命令来启动调试会话,更常用的命令是dlvdebug、dlvexec和dlvtest。限于篇幅,本文介绍如何使用dlvdebug。示例代码:packagemainimport("fmt")funcmain(){a:=1b:=2c:=sum(a,b)fmt.Println(c)}funcsum(a,bint)int{res:=a+breturnres}阅读上面我们将用于调试会话的代码示例,它包含一个主函数和一个求和函数,主函数定义变量a和变量b,调用子函数,然后返回结果给变量c赋值,最后打印变量c的值。启动调试会话:[root@VM-8-14-centoswork]#dlvdebugType'help'命令列表。(dlv)阅读上面的代码,我们使用dlvdebug启动一个不带任何参数的调试会话的情况下,Delve编译并启动调试当前目录下的主包。我们还可以指定一个文件名,Delve将编译指定文件的主包并启动调试会话。[root@VM-8-14-centoswork]#dlvdebugmain.goType'help'查看命令列表。(dlv)调试会话启动后,我们就可以使用调试命令来调试程序了。列表命令:dlvdebugType'help'命令列表。(dlv)listmain.mainShowing/work/main.go:7(PC:0x49670a)2:3:import(4:"fmt"5:)6:7:funcmain(){8:a:=19:b:=210:c:=sum(a,b)11:fmt.Println(c)12:}(dlv)list./main.go:7显示/work/main.go:7(PC:0x49670a)2:3:import(4:"fmt"5:)6:7:funcmain(){8:a:=19:b:=210:c:=sum(a,b)11:fmt.Println(c)12:}(dlv)调试会话开始后,我们可以使用list命令列出指定位置的源代码,包括两种方式,第一种方式是,第二种方式是:。breakcommand:dlvdebugType'help'forlistofcommands.(dlv)breakmain.mainBreakpoint1setat0x49670aformain.main()./main.go:7(dlv)我们可以使用break命令添加断点,并且和list命令一样,也可以使用上面两种方法来添加断点位置。我们可以使用breakpoints命令列出所有断点,使用clear命令删除指定断点,使用clearall删除所有断言。continue、next、step、stepout和print命令:dlvdebugType'help'forlistofcommands.(dlv)breakmain.mainBreakpoint1setat0x49670aformain.main()./main.go:7(dlv)continue>main.main()./main.go:7(hitsgoroutine(1):1total:1)(PC:0x49670a)2:3:import(4:"fmt"5:)6:=>7:funcmain(){8:a:=19:b:=210:c:=sum(a,b)11:fmt.Println(c)12:}(dlv)next>main.main()./main.go:8(PC:0x496718)3:import(4:"fmt"5:)6:7:funcmain(){=>8:a:=19:b:=210:c:=sum(a,b)11:fmt.Println(c)12:}13:(dlv)next>main.main()./main.go:9(PC:0x496721)4:"fmt"5:)6:7:funcmain(){8:a:=1=>9:b:=210:c:=sum(a,b)11:fmt.Println(c)12:}13:14:funcsum(a,bint)int{(dlv)next>main.main()./main.go:10(PC:0x49672a)5:)6:7:funcmain(){8:a:=19:b:=2=>10:c:=sum(a,b)11:fmt.Println(c)12:}13:14:funcsum(a,bint)int{15:res:=a+b(dlv)打印a1(dlv)打印b2(dlv)步骤>main.sum()./main.go:14(PC:0x4967e0)9:b:=210:c:=sum(a,b)11:fmt.Println(c)12:}13:=>14:funcsum(a,bint)int{15:res:=a+b16:returnres17:}(dlv)next>main.sum()./main.go:15(PC:0x496800)10:c:=sum(a,b)11:fmt.Println(c)12:}13:14:funcsum(a,bint)int{=>15:res:=a+b16:returnres17:}(dlv)next>main.sum()./main.go:16(PC:0x49680f)11:fmt.Println(c)12:}13:14:funcsum(a,bint)int{15:res:=a+b=>16:returnres17:}(dlv)next>main.main()./main.go:10(PC:0x496739)返回值:~r0:35:)6:7:funcmain(){8:a:=19:b:=2=>10:c:=sum(a,b)11:fmt.Println(c)12:}13:14:funcsum(a,bint)int{15:res:=a+b(dlv)next>main.main()./main.go:11(PC:0x49673e)6:7:funcmain(){8:a:=19:b:=210:c:=sum(a,b)=>11:fmt.Println(c)12:}13:14:funcsum(a,bint)int{15:res:=a+b16:returnres(dlv)printc3(dlv)看上面的代码,我们使用Delve添加断点后,执行continue命令,程序会执行到断点位置;executeNext命令,程序继续执行下一行代码;执行step命令,程序进入调用函数;执行stepout命令,程序跳出到调用函数的调用位置;执行打印命令,打印指定参数的值。读者朋友们使用上面的命令,可以满足大部分的调试场景。为便于理解,上述示例中使用的命令均未使用缩写形式。在实际使用中,使用缩写形式更方便。简写形式:break(b)continue(c)next(n)step(s)stepout(so)print(p)04总结本文简单介绍了Go语言调试器Delve的基本使用方法,读者朋友可以调试程序使用Delve时,将调试代码替换为打印。