首页>>后端>>Golang->你是使用什么工具调试 golang 程序的?

你是使用什么工具调试 golang 程序的?

时间:2023-11-30 本站 点击:0

写过 C/C++ 的都是到,调试程序的时候通常使用 gdb 工具来进行调试,用起来可爽了,那么 gdb 是否也适合 golang 程序的调试呢?

我个人到是通常使用 dlv 来进行 golang 程序的调试,分享一波。

dlv全称 Delve,Delve 可以让你通过控制程序的执行来与程序进行交互,他可以计算变量,并提供线程 / goroutine 状态、CPU 寄存器状态等信息。

Delve 的目标是为调试 Go 程序提供一个简单强大的调试功能。

尝试看一下 dlv 的 help 信息

Usage:dlv[command]AvailableCommands:attachAttachtorunningprocessandbegindebugging.connectConnecttoaheadlessdebugserver.coreExamineacoredump.dap[EXPERIMENTAL]StartsaheadlessTCPservercommunicatingviaDebugAdaptorProtocol(DAP).debugCompileandbegindebuggingmainpackageincurrentdirectory,orthepackagespecified.execExecuteaprecompiledbinary,andbeginadebugsession.helpHelpaboutanycommandrunDeprecatedcommand.Use'debug'instead.testCompiletestbinaryandbegindebuggingprogram.traceCompileandbegintracingprogram.versionPrintsversion.

通过 help 我们可以看到可以使用这些命令来调试我们的程序,根据不同的应用场景

例如,我们直接编译并调试的时候就可以使用 dlv debug

调试一个正在运行的程序,就可以使用 dlv attach

调试一个编译好的二进制文件,可以使用 dlv exec

其他的使用方式也类似,看上述的英文大概就知道啥意思了

开始调试小程序

简单写一个小程序来应用一下这个调试工具

constNUM=10funcmain(){arr:=make([]int,NUM)fori:=1;i<NUM;i++{arr[i]=i+ifmt.Printf("arr[%d]==%d\n",i,arr[i])}fmt.Println("programover")}

1、使用 dlv debug main.go 开始调试

>dlvdebugmain.goType'help'forlistofcommands.(dlv)

2、dlv 里面使用 help 查看一下可以使用哪些命令

这些命令对应的解释相对还是比较清楚的,我们可以来用一下

3、使用 break 打给 main 函数一个端点,或者是用 b

(dlv)bmain.mainBreakpoint1setat0xef84eaformain.main()d:/mycode/my_new_first/dlvtest/main.go:7

给 main 函数打 1 断点,断点号是 1

4、continue 继续执行代码,直到运行到 main 的中断

(dlv)c>main.main()d:/mycode/my_new_first/dlvtest/main.go:7(hitsgoroutine(1):1total:1)(PC:0xef84ea)2:3:import"fmt"4:5:constNUM=106:=>7:funcmain(){8:arr:=make([]int,NUM)9:10:fori:=1;i<NUM;i++{11:arr[i]=i+i12:fmt.Printf("arr[%d]==%d\n",i,arr[i])

5、再 打一个断点,加上具体的条件

b文件:行数

condition中断号 具体的条件

(dlv)bmain.go:12Breakpoint2setat0xef85a4formain.main()d:/mycode/my_new_first/dlvtest/main.go:12(dlv)condition2i==7

6、continue继续执行代码

(dlv)carr[1]==2arr[2]==4arr[3]==6arr[4]==8arr[5]==10arr[6]==12>main.main()d:/mycode/my_new_first/dlvtest/main.go:12(hitsgoroutine(1):1total:1)(PC:0xef85a4)7:funcmain(){8:arr:=make([]int,NUM)9:10:fori:=1;i<NUM;i++{11:arr[i]=i+i=>12:fmt.Printf("arr[%d]==%d\n",i,arr[i])13:}14:fmt.Println("programover")15:}

7、locals 查看本地变量信息 , p/print 打印变量信息

(dlv)localsarr=[]intlen:10,cap:10,[...]i=7(dlv)args(noargs)(dlv)pi7(dlv)parr[]intlen:10,cap:10,[0,2,4,6,8,10,12,14,0,0]

使用 p 查看多个变量的信息,打印出具体的值

8、bp/breakpoints 查看中断列表 , clear 清空中断

查看中断列表

清空其中一个中断

再查看中断列表看看效果

(dlv)bpBreakpointruntime-fatal-throw(enabled)at0xe6ca00forruntime.throw()c:/programfiles/go/src/runtime/panic.go:1107(0)Breakpointunrecovered-panic(enabled)at0xe6cc80forruntime.fatalpanic()c:/programfiles/go/src/runtime/panic.go:1190(0)printruntime.curg._panic.argBreakpoint1(enabled)at0xef84eaformain.main()d:/mycode/my_new_first/dlvtest/main.go:7(1)Breakpoint2(enabled)at0xef85a4formain.main()d:/mycode/my_new_first/dlvtest/main.go:12(1)condi==7(dlv)clear2Breakpoint2clearedat0xef85a4formain.main()d:/mycode/my_new_first/dlvtest/main.go:12(dlv)bpBreakpointruntime-fatal-throw(enabled)at0xe6ca00forruntime.throw()c:/programfiles/go/src/runtime/panic.go:1107(0)Breakpointunrecovered-panic(enabled)at0xe6cc80forruntime.fatalpanic()c:/programfiles/go/src/runtime/panic.go:1190(0)printruntime.curg._panic.argBreakpoint1(enabled)at0xef84eaformain.main()d:/mycode/my_new_first/dlvtest/main.go:7(1)

9、ls 查看当前代码运行的位置 ,next 执行源码的下一行

(dlv)ls>main.main()d:/mycode/my_new_first/dlvtest/main.go:12(hitstotal:0)(PC:0xef85a4)7:funcmain(){8:arr:=make([]int,NUM)9:10:fori:=1;i<NUM;i++{11:arr[i]=i+i=>12:fmt.Printf("arr[%d]==%d\n",i,arr[i])13:}14:fmt.Println("programover")15:}
constNUM=10funcmain(){arr:=make([]int,NUM)fori:=1;i<NUM;i++{arr[i]=i+ifmt.Printf("arr[%d]==%d\n",i,arr[i])}fmt.Println("programover")}0

通过箭头我们就可以看出来 ,没有毛病

10、bt/stack 打印堆栈信息

constNUM=10funcmain(){arr:=make([]int,NUM)fori:=1;i<NUM;i++{arr[i]=i+ifmt.Printf("arr[%d]==%d\n",i,arr[i])}fmt.Println("programover")}1

查看堆栈信息,可以直接看到汇编里面的具体信息

11、goroutines 查看程序中的协程列表,以及其对应的代码行数

constNUM=10funcmain(){arr:=make([]int,NUM)fori:=1;i<NUM;i++{arr[i]=i+ifmt.Printf("arr[%d]==%d\n",i,arr[i])}fmt.Println("programover")}2

goroutine 执行的时候默认是查看当前协程的信息,上面打印可以知道,总共有 5 个协程,当前打印的协程信息是第 1 个

12、goroutine 显示当前当前协程的具体信息和切换协程

主动切换到 第 2 个协程,并查看当前协程的信息

constNUM=10funcmain(){arr:=make([]int,NUM)fori:=1;i<NUM;i++{arr[i]=i+ifmt.Printf("arr[%d]==%d\n",i,arr[i])}fmt.Println("programover")}3

工具需要用起来才有意义。

好了,本次就到这里。

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是小魔童哪吒,欢迎点赞关注收藏,下次见~


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/Golang/4592.html