dlv调试实践
dlv调试实践
案例一:通过dlv debug进行源码调试
(1.)新建main.go,并执行go mod init
package main
import (
"fmt"
)
func main() {
nums := make([]int, 5)
for i := 0; i <len(nums); i++ {
nums[i] = i * i
}
fmt.Println(nums)
}
(2.)执行dlv debug进入调试模式
[root@localhost demo-1]# dlv debug
Type 'help' for list of commands.
# 设置断点:main.main
(dlv) b main.main
Breakpoint 1 set at 0x49aeea for main.main() ./main.go:7
# 查看已设置的所有断点,我们发现除了我们自己设置的 main.main 函数断点外,Delve 内部已经为 panic 异常函数设置了一个断点。
(dlv) bp
Breakpoint runtime-fatal-throw (enabled) at 0x437a40,0x437940 for (multiple functions)() /usr/local/go/src/runtime/panic.go:1059 (0)
Breakpoint unrecovered-panic (enabled) at 0x437e00 for runtime.fatalpanic() /usr/local/go/src/runtime/panic.go:1143 (0)
print runtime.curg._panic.arg
Breakpoint 1 (enabled) at 0x49aeea for main.main() ./main.go:7 (0)
# 查看全局变量(可通过正则参数过滤)
(dlv) vars main
runtime.main_init_done = chan bool nil
runtime.mainStarted = false
# 运行到下个断点处
(dlv) c
> main.main() ./main.go:7 (hits goroutine(1):1 total:1) (PC: 0x49aeea)
2:
3: import (
4: "fmt"
5: )
6:
=> 7: func main() {
8: nums := make([]int, 5)
9: for i := 0; i <len(nums); i++ {
10: nums[i] = i * i
11: }
12: fmt.Println(nums)
# 单步执行
(dlv) n
> main.main() ./main.go:8 (PC: 0x49aef8)
3: import (
4: "fmt"
5: )
6:
7: func main() {
=> 8: nums := make([]int, 5)
9: for i := 0; i <len(nums); i++ {
10: nums[i] = i * i
11: }
12: fmt.Println(nums)
13: }
# 查看传入函数的参数
(dlv) args
(no args)
# 查看局部变量
(dlv) locals
(no locals)
# 再下一步,初始化nums了,可以看到有局部变量了
(dlv) n
> main.main() ./main.go:9 (PC: 0x49af23)
4: "fmt"
5: )
6:
7: func main() {
8: nums := make([]int, 5)
=> 9: for i := 0; i <len(nums); i++ {
10: nums[i] = i * i
11: }
12: fmt.Println(nums)
13: }
(dlv) locals
nums = []int len: 5, cap: 5, [...]
(dlv) args
(no args)
# 组和使用 break 和 condition 命令设置条件断点
(dlv) b main.go:10
Breakpoint 2 set at 0x49af42 for main.main() ./main.go:10
(dlv) bp
Breakpoint runtime-fatal-throw (enabled) at 0x437940,0x437a40 for (multiple functions)() /usr/local/go/src/runtime/panic.go:1059 (0)
Breakpoint unrecovered-panic (enabled) at 0x437e00 for runtime.fatalpanic() /usr/local/go/src/runtime/panic.go:1143 (0)
print runtime.curg._panic.arg
Breakpoint 1 (enabled) at 0x49aeea for main.main() ./main.go:7 (1)
Breakpoint 2 (enabled) at 0x49af42 for main.main() ./main.go:10 (0)
# 这里设置条件断点 i 等于 3
(dlv) cond 2 i==3
# 继续 continue 执行到刚设置的条件断点,输出局部变量
(dlv) c
> main.main() ./main.go:10 (hits goroutine(1):1 total:1) (PC: 0x49af42)
5: )
6:
7: func main() {
8: nums := make([]int, 5)
9: for i := 0; i <len(nums); i++ {
=> 10: nums[i] = i * i
11: }
12: fmt.Println(nums)
13: }
(dlv) locals
nums = []int len: 5, cap: 5, [...]
i = 3
(dlv) print nums
[]int len: 5, cap: 5, [0,1,4,0,0]
# 查看栈帧信息
(dlv) stack
0 0x000000000049af42 in main.main
at ./main.go:10
1 0x000000000043a138 in runtime.main
at /usr/local/go/src/runtime/proc.go:250
2 0x0000000000464cc1 in runtime.goexit
at /usr/local/go/src/runtime/asm_amd64.s:1594
(dlv) n
> main.main() ./main.go:9 (PC: 0x49af73)
4: "fmt"
5: )
6:
7: func main() {
8: nums := make([]int, 5)
=> 9: for i := 0; i <len(nums); i++ {
10: nums[i] = i * i
11: }
12: fmt.Println(nums)
13: }
(dlv) b main.go:12
Breakpoint 3 set at 0x49af82 for main.main() ./main.go:12
(dlv) c
> main.main() ./main.go:12 (hits goroutine(1):1 total:1) (PC: 0x49af82)
7: func main() {
8: nums := make([]int, 5)
9: for i := 0; i <len(nums); i++ {
10: nums[i] = i * i
11: }
=> 12: fmt.Println(nums)
13: }
(dlv) print nums
[]int len: 5, cap: 5, [0,1,4,9,16]
(dlv) q
案例二:使用dlv attach 进行调试
(1.)新建main.go,并进行go mod init
package main
import (
"log"
"net/http"
)
func main() {
http.HandleFunc("/hello", func(writer http.ResponseWriter, request *http.Request) {
nums := make([]int, 5)
for i := 0; i < len(nums); i++ {
nums[i] = i * i
}
writer.Write([]byte("OK"))
})
err := http.ListenAndServe(":4781", nil)
if err != nil {
log.Fatalln(err)
}
}
(2.) 编译,禁用编译器优化
go build -gcflags="all=-N -l" main.go
// 运行
./main
(3.)获取进程ID
ps -ef |grep main
(4.)进入调试
dlv attach $pid // pid为当前进程的pid
(5.)示例如下:
[root@localhost ~]# dlv attach 18175
Type 'help' for list of commands.
# 在main函数12行进行断点
(dlv) b main.go:12
Breakpoint 1 set at 0x74078e for main.main.func1() /home/nova000918/workspace/gocode/src/demo-1/main.go:12
# 查看断点
(dlv) bp
Breakpoint runtime-fatal-throw (enabled) at 0x43d380,0x43d480 for (multiple functions)() /usr/local/go/src/runtime/panic.go:1059 (0)
Breakpoint unrecovered-panic (enabled) at 0x43d840 for runtime.fatalpanic() /usr/local/go/src/runtime/panic.go:1143 (0)
print runtime.curg._panic.arg
Breakpoint 1 (enabled) at 0x74078e for main.main.func1() /home/nova000918/workspace/gocode/src/demo-1/main.go:12 (0)
# 继续直到断点处卡住,这里发送http请求,curl http://127.0.0.1:4781/hello 会进入断点
(dlv) c
> main.main.func1() /home/nova000918/workspace/gocode/src/demo-1/main.go:12 (hits goroutine(6):1 total:1) (PC: 0x74078e)
7:
8: func main() {
9: http.HandleFunc("/hello", func(writer http.ResponseWriter, request *http.Request) {
10: nums := make([]int, 5)
11: for i := 0; i < len(nums); i++ {
=> 12: nums[i] = i * i
13: }
14: writer.Write([]byte("OK"))
15: })
16:
17: err := http.ListenAndServe(":4781", nil)
# 打印变量
(dlv) print nums
[]int len: 5, cap: 5, [0,0,0,0,0]
# 查看本地变量
(dlv) locals
nums = []int len: 5, cap: 5, [...]
i = 0
# 下一步
(dlv) n
> main.main.func1() /home/nova000918/workspace/gocode/src/demo-1/main.go:11 (PC: 0x7407be)
6: )
7:
8: func main() {
9: http.HandleFunc("/hello", func(writer http.ResponseWriter, request *http.Request) {
10: nums := make([]int, 5)
=> 11: for i := 0; i < len(nums); i++ {
12: nums[i] = i * i
13: }
14: writer.Write([]byte("OK"))
15: })
16:
(dlv) n
> main.main.func1() /home/nova000918/workspace/gocode/src/demo-1/main.go:12 (hits goroutine(6):2 total:2) (PC: 0x74078e)
7:
8: func main() {
9: http.HandleFunc("/hello", func(writer http.ResponseWriter, request *http.Request) {
10: nums := make([]int, 5)
11: for i := 0; i < len(nums); i++ {
=> 12: nums[i] = i * i
13: }
14: writer.Write([]byte("OK"))
15: })
16:
17: err := http.ListenAndServe(":4781", nil)
(dlv) print nums
[]int len: 5, cap: 5, [0,0,0,0,0]
(dlv) locals
nums = []int len: 5, cap: 5, [...]
(dlv) print nums
[]int len: 5, cap: 5, [0,1,4,9,16]
(dlv) q
【励志篇】:
古之成大事掌大学问者,不惟有超世之才,亦必有坚韧不拔之志。