共计 5959 个字符,预计需要花费 15 分钟才能阅读完成。
写过 C/C++ 的都是到,调试程序的时候通常应用 gdb 工具来进行调试,用起来可爽了,那么 gdb 是否也适宜 golang 程序的调试的
我集体到是通常应用 dlv 来进行 golang 程序的调试,分享一波
dlv 是什么,全称 Delve
Delve 能够让你通过控制程序的执行来与程序进行交互,他能够计算变量,并提供线程 / goroutine 状态、CPU 寄存器状态等信息
Delve 的指标是为调试 Go 程序提供一个简略弱小的调试性能
尝试看一下 dlv 的 help 信息
Usage:
dlv [command]
Available Commands:
attach Attach to running process and begin debugging.
connect Connect to a headless debug server.
core Examine a core dump.
dap [EXPERIMENTAL] Starts a headless TCP server communicating via Debug Adaptor Protocol (DAP).
debug Compile and begin debugging main package in current directory, or the package specified.
exec Execute a precompiled binary, and begin a debug session.
help Help about any command
run Deprecated command. Use 'debug' instead.
test Compile test binary and begin debugging program.
trace Compile and begin tracing program.
version Prints version.
通过 help 咱们能够看到能够应用这些命令来调试咱们的程序,依据不同的利用场景
例如,
咱们间接编译并调试的时候就能够应用 dlv debug
调试一个正在运行的程序,就能够应用 dlv attach
调试一个编译好的二进制文件,能够应用 dlv exec
其余的应用形式也相似,看上述的英文大略就晓得啥意思了
开始调试小程序
简略写一个小程序来利用一下这个调试工具
const NUM = 10
func main() {arr := make([]int, NUM)
for i := 1; i < NUM; i++ {arr[i] = i + i
fmt.Printf("arr[%d] == %d\n", i, arr[i])
}
fmt.Println("program over")
}
1、应用 dlv debug main.go 开始调试
>dlv debug main.go
Type 'help' for list of commands.
(dlv)
2、dlv 外面应用 help 查看一下能够应用哪些命令
这些命令对应的解释绝对还是比较清楚的,咱们能够来用一下
3、应用 break
打给 main 函数一个端点,或者是用 b
(dlv) b main.main
Breakpoint 1 set at 0xef84ea for main.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 (hits goroutine(1):1 total:1) (PC: 0xef84ea)
2:
3: import "fmt"
4:
5: const NUM = 10
6:
=> 7: func main() {8: arr := make([]int, NUM)
9:
10: for i := 1; i < NUM; i++ {11: arr[i] = i + i
12: fmt.Printf("arr[%d] == %d\n", i, arr[i])
5、再 打一个断点,加上具体的条件
b
文件: 行数condition
中断号 具体的条件
(dlv) b main.go:12
Breakpoint 2 set at 0xef85a4 for main.main() d:/mycode/my_new_first/dlvtest/main.go:12
(dlv) condition 2 i==7
6、continue
继续执行代码
(dlv) c
arr[1] == 2
arr[2] == 4
arr[3] == 6
arr[4] == 8
arr[5] == 10
arr[6] == 12
> main.main() d:/mycode/my_new_first/dlvtest/main.go:12 (hits goroutine(1):1 total:1) (PC: 0xef85a4)
7: func main() {8: arr := make([]int, NUM)
9:
10: for i := 1; i < NUM; i++ {11: arr[i] = i + i
=> 12: fmt.Printf("arr[%d] == %d\n", i, arr[i])
13: }
14: fmt.Println("program over")
15: }
7、locals
查看本地变量信息,p/print
打印变量信息
(dlv) locals
arr = []int len: 10, cap: 10, [...]
i = 7
(dlv) args
(no args)
(dlv) p i
7
(dlv) p arr
[]int len: 10, cap: 10, [0,2,4,6,8,10,12,14,0,0]
- 应用
p
查看多个变量的信息,打印出具体的值
8、bp/breakpoints
查看中断列表,clear
清空中断
- 查看中断列表
- 清空其中一个中断
- 再查看中断列表看看成果
(dlv) bp
Breakpoint runtime-fatal-throw (enabled) at 0xe6ca00 for runtime.throw() c:/program files/go/src/runtime/panic.go:1107 (0)
Breakpoint unrecovered-panic (enabled) at 0xe6cc80 for runtime.fatalpanic() c:/program files/go/src/runtime/panic.go:1190 (0)
print runtime.curg._panic.arg
Breakpoint 1 (enabled) at 0xef84ea for main.main() d:/mycode/my_new_first/dlvtest/main.go:7 (1)
Breakpoint 2 (enabled) at 0xef85a4 for main.main() d:/mycode/my_new_first/dlvtest/main.go:12 (1)
cond i == 7
(dlv) clear 2
Breakpoint 2 cleared at 0xef85a4 for main.main() d:/mycode/my_new_first/dlvtest/main.go:12
(dlv) bp
Breakpoint runtime-fatal-throw (enabled) at 0xe6ca00 for runtime.throw() c:/program files/go/src/runtime/panic.go:1107 (0)
Breakpoint unrecovered-panic (enabled) at 0xe6cc80 for runtime.fatalpanic() c:/program files/go/src/runtime/panic.go:1190 (0)
print runtime.curg._panic.arg
Breakpoint 1 (enabled) at 0xef84ea for main.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 (hits total:0) (PC: 0xef85a4)
7: func main() {8: arr := make([]int, NUM)
9:
10: for i := 1; i < NUM; i++ {11: arr[i] = i + i
=> 12: fmt.Printf("arr[%d] == %d\n", i, arr[i])
13: }
14: fmt.Println("program over")
15: }
(dlv) next
> main.main() d:/mycode/my_new_first/dlvtest/main.go:12 (hits total:0) (PC: 0xef85a4)
7: func main() {8: arr := make([]int, NUM)
9:
10: for i := 1; i < NUM; i++ {11: arr[i] = i + i
12: fmt.Printf("arr[%d] == %d\n", i, arr[i])
=> 13: }
14: fmt.Println("program over")
15: }
通过箭头咱们就可以看进去,没有故障
10、bt/stack
打印堆栈信息
(dlv) bt
0 0x0000000000ef85a4 in main.main
at d:/mycode/my_new_first/dlvtest/main.go:12
1 0x0000000000e6f2f6 in runtime.main
at c:/program files/go/src/runtime/proc.go:225
2 0x0000000000e9f3a1 in runtime.goexit
at c:/program files/go/src/runtime/asm_amd64.s:1371
查看堆栈信息,能够间接看到汇编外面的具体信息
11、goroutines
查看程序中的协程列表,以及其对应的代码行数
(dlv) goroutines
* Goroutine 1 - User: d:/mycode/my_new_first/dlvtest/main.go:12 main.main (0xef85a4) (thread 26592)
Goroutine 2 - User: c:/program files/go/src/runtime/proc.go:337 runtime.gopark (0xe6f6f6) [force gc (idle)]
Goroutine 3 - User: c:/program files/go/src/runtime/proc.go:337 runtime.gopark (0xe6f6f6) [GC sweep wait]
Goroutine 4 - User: c:/program files/go/src/runtime/proc.go:337 runtime.gopark (0xe6f6f6) [GC scavenge wait]
Goroutine 5 - User: c:/program files/go/src/runtime/proc.go:337 runtime.gopark (0xe6f6f6) [finalizer wait]
[5 goroutines]
(dlv) goroutine
Thread 26592 at d:/mycode/my_new_first/dlvtest/main.go:12
Goroutine 1:
Runtime: d:/mycode/my_new_first/dlvtest/main.go:12 main.main (0xef85a4)
User: d:/mycode/my_new_first/dlvtest/main.go:12 main.main (0xef85a4)
Go: c:/program files/go/src/runtime/asm_amd64.s:226 runtime.rt0_go (0xe9d3cc)
Start: c:/program files/go/src/runtime/proc.go:115 runtime.main (0xe6f0e0)
goroutine 执行的时候默认是查看以后协程的信息,下面打印能够晓得,总共有 5 个协程,以后打印的协程信息是第 1 个
12、goroutine
显示以后以后协程的具体信息和切换协程
被动切换到 第 2 个协程,并查看以后协程的信息
(dlv) goroutine 2
Switched from 1 to 2 (thread 26592)
(dlv) goroutine
Thread 26592 at d:/mycode/my_new_first/dlvtest/main.go:12
Goroutine 2:
Runtime: c:/program files/go/src/runtime/proc.go:337 runtime.gopark (0xe6f6f6)
User: c:/program files/go/src/runtime/proc.go:337 runtime.gopark (0xe6f6f6)
Go: c:/program files/go/src/runtime/proc.go:264 runtime.init.6 (0xe6f47c)
Start: c:/program files/go/src/runtime/proc.go:267 runtime.forcegchelper (0xe6f4a0)
(dlv) goroutines
Goroutine 1 - User: d:/mycode/my_new_first/dlvtest/main.go:12 main.main (0xef85a4) (thread 26592)
* Goroutine 2 - User: c:/program files/go/src/runtime/proc.go:337 runtime.gopark (0xe6f6f6) [force gc (idle)]
Goroutine 3 - User: c:/program files/go/src/runtime/proc.go:337 runtime.gopark (0xe6f6f6) [GC sweep wait]
Goroutine 4 - User: c:/program files/go/src/runtime/proc.go:337 runtime.gopark (0xe6f6f6) [GC scavenge wait]
Goroutine 5 - User: c:/program files/go/src/runtime/proc.go:337 runtime.gopark (0xe6f6f6) [finalizer wait]
[5 goroutines]
工具须要用起来才有意义
好了,本次就到这里
技术是凋谢的,咱们的心态,更应是凋谢的。拥抱变动,背阴而生,致力向前行。
我是 阿兵云原生,欢送点赞关注珍藏,下次见~