学习笔记-代码调试工具

简介: dlv(delve的简称)是一个强大的Go源代码级调试工具,通过控制程序执行、计算变量及提供线程/协程状态等信息,为调试Go程序提供了简单且功能丰富的界面。在macOS上,可以通过`brew install dlv`命令安装。下面是一个使用dlv调试Go代码的例子,展示了如何设置断点并逐步执行代码,检查变量值和函数内部细节。常用命令包括:`b`(打断点)、`p`(打印变量)、`n`(下一步)、`c`(继续执行)、`args`(打印参数)、`locals`(打印局部变量)、`l`(列出代码)、`bp`(显示断点)和`q`(退出)。

1.dlv 简介
• dlv(delve 的简写) 是一个用于 Go 源代码级调试器。
• dlv 通过控制进程的执行、计算变量、提供线程/协程的状态、CPU寄存器状态等信息,可以方便地与程序进行交互。
• 这个工具的目标是为调试 Go 程序提供一个简单但功能强大的界面。
• dlv 将标志传递给正在调试的程序,例如:
dlv exec ./hello -- server --config conf/config.toml
• macOs 使用 brew install dlv 命令下载安装即可。
2.dlv 调试代码
2.1 dlv 剖析 strings.Contains 函数
新建 a.go 文件,文件内容如下:
package main
import (
"fmt"
"strings"
)
func main() {
str := "Go语言是世界上最好的语言"
if strings.Contains(str,"世界") {
fmt.Println("字符串中包含","世界")
}else {
fmt.Println("字符串中不包含","世界")
}
}
使用 dlv debug a.go 命令可以开始对上述代码进行断点调试:
qinshixian@qinshixiandeMacBook-Pro qinshixian % dlv debug a.go
Type 'help' for list of commands.
(dlv) b main.main
Breakpoint 1 set at 0x10acd6f for main.main() ./a.go:8
(dlv) c

main.main() ./a.go:8 (hits goroutine(1):1 total:1) (PC: 0x10acd6f)
3: import (
4: "fmt"
5: "strings"
6: )
7:
=> 8: func main() {
9: str := "Go语言是世界上最好的语言"
10: if strings.Contains(str,"世界") {
11: fmt.Println("字符串中包含","世界")
12: }else {
13: fmt.Println("字符串中不包含","世界")
(dlv) n
main.main() ./a.go:9 (PC: 0x10acd86)
4: "fmt"
5: "strings"
6: )
7:
8: func main() {
=> 9: str := "Go语言是世界上最好的语言"
10: if strings.Contains(str,"世界") {
11: fmt.Println("字符串中包含","世界")
12: }else {
13: fmt.Println("字符串中不包含","世界")
14: }
(dlv) n
main.main() ./a.go:10 (PC: 0x10acd9b)
5: "strings"
6: )
7:
8: func main() {
9: str := "Go语言是世界上最好的语言"
=> 10: if strings.Contains(str,"世界") {
11: fmt.Println("字符串中包含","世界")
12: }else {
13: fmt.Println("字符串中不包含","世界")
14: }
15: }
(dlv) p str
"Go语言是世界上最好的语言"
(dlv) s strings.Contains
strings.Contains() /Users/qinshixian/.g/go/src/strings/strings.go:61 (PC: 0x10ac1e6)
56: s = s[i+len(substr):]
57: }
58: }
59:
60: // Contains reports whether substr is within s.
=> 61: func Contains(s, substr string) bool {
62: return Index(s, substr) >= 0
63: }
64:
65: // ContainsAny reports whether any Unicode code points in chars are within s.
66: func ContainsAny(s, chars string) bool {
(dlv) n
strings.Contains() /Users/qinshixian/.g/go/src/strings/strings.go:62 (PC: 0x10ac20d)
57: }
58: }
59:
60: // Contains reports whether substr is within s.
61: func Contains(s, substr string) bool {
=> 62: return Index(s, substr) >= 0
63: }
64:
65: // ContainsAny reports whether any Unicode code points in chars are within s.
66: func ContainsAny(s, chars string) bool {
67: return IndexAny(s, chars) >= 0
(dlv) b Contains
Breakpoint 2 set at 0x10ac1e6 for strings.Contains() /Users/qinshixian/.g/go/src/strings/strings.go:61
(dlv) p s
"Go语言是世界上最好的语言"
(dlv) p substr
"世界"
(dlv) s Index
strings.Index() /Users/qinshixian/.g/go/src/strings/strings.go:1024 (PC: 0x10ac32f)
1019: // One string is empty. Are both?
1020: return s == t
1021: }
1022:
1023: // Index returns the index of the first instance of substr in s, or -1 if substr is not present in s.
=>1024: func Index(s, substr string) int {
1025: n := len(substr)
1026: switch {
1027: case n == 0:
1028: return 0
1029: case n == 1:
(dlv) n
strings.Index() /Users/qinshixian/.g/go/src/strings/strings.go:1025 (PC: 0x10ac36f)
1020: return s == t
1021: }
1022:
1023: // Index returns the index of the first instance of substr in s, or -1 if substr is not present in s.
1024: func Index(s, substr string) int {
=>1025: n := len(substr)
1026: switch {
1027: case n == 0:
1028: return 0
1029: case n == 1:
1030: return IndexByte(s, substr[0])
(dlv) n
strings.Index() /Users/qinshixian/.g/go/src/strings/strings.go:1027 (PC: 0x10ac380)
1022:
1023: // Index returns the index of the first instance of substr in s, or -1 if substr is not present in s.
1024: func Index(s, substr string) int {
1025: n := len(substr)
1026: switch {
=>1027: case n == 0:
1028: return 0
1029: case n == 1:
1030: return IndexByte(s, substr[0])
1031: case n == len(s):
1032: if substr == s {
(dlv) p n
6
(dlv) p len(s)
35
(dlv) n
strings.Index() /Users/qinshixian/.g/go/src/strings/strings.go:1029 (PC: 0x10ac3a4)
1024: func Index(s, substr string) int {
1025: n := len(substr)
1026: switch {
1027: case n == 0:
1028: return 0
=>1029: case n == 1:
1030: return IndexByte(s, substr[0])
1031: case n == len(s):
1032: if substr == s {
1033: return 0
1034: }
(dlv) n
strings.Index() /Users/qinshixian/.g/go/src/strings/strings.go:1031 (PC: 0x10ac403)
1026: switch {
1027: case n == 0:
1028: return 0
1029: case n == 1:
1030: return IndexByte(s, substr[0])
=>1031: case n == len(s):
1032: if substr == s {
1033: return 0
1034: }
1035: return -1
1036: case n > len(s):
(dlv)
strings.Index() /Users/qinshixian/.g/go/src/strings/strings.go:1036 (PC: 0x10ac494)
1031: case n == len(s):
1032: if substr == s {
1033: return 0
1034: }
1035: return -1
=>1036: case n > len(s):
1037: return -1
1038: case n <= bytealg.MaxLen:
1039: // Use brute force when s and substr both are small
1040: if len(s) <= bytealg.MaxBruteForce {
1041: return bytealg.IndexString(s, substr)
(dlv) n
strings.Index() /Users/qinshixian/.g/go/src/strings/strings.go:1038 (PC: 0x10ac4cf)
1033: return 0
1034: }
1035: return -1
1036: case n > len(s):
1037: return -1
=>1038: case n <= bytealg.MaxLen:
1039: // Use brute force when s and substr both are small
1040: if len(s) <= bytealg.MaxBruteForce {
1041: return bytealg.IndexString(s, substr)
1042: }
1043: c0 := substr[0]
(dlv) p bytealg.MaxLen
63
(dlv) n
strings.Index() /Users/qinshixian/.g/go/src/strings/strings.go:1040 (PC: 0x10ac4e7)
1035: return -1
1036: case n > len(s):
1037: return -1
1038: case n <= bytealg.MaxLen:
1039: // Use brute force when s and substr both are small
=>1040: if len(s) <= bytealg.MaxBruteForce {
1041: return bytealg.IndexString(s, substr)
1042: }
1043: c0 := substr[0]
1044: c1 := substr[1]
1045: i := 0
(dlv) p len(s)
35
(dlv) p bytealg.MaxBruteForce
64
(dlv) n
strings.Index() /Users/qinshixian/.g/go/src/strings/strings.go:1041 (PC: 0x10ac4ff)
1036: case n > len(s):
1037: return -1
1038: case n <= bytealg.MaxLen:
1039: // Use brute force when s and substr both are small
1040: if len(s) <= bytealg.MaxBruteForce {
=>1041: return bytealg.IndexString(s, substr)
1042: }
1043: c0 := substr[0]
1044: c1 := substr[1]
1045: i := 0
1046: t := len(s) - n + 1
(dlv) s bytealg.IndexString
internal/bytealg.IndexString() /Users/qinshixian/.g/go/src/internal/bytealg/index_amd64.s:18 (PC: 0x1002840)
Warning: debugging optimized function
13: MOVQ DI, R10
14: LEAQ ret+48(FP), R11
15: JMP indexbody<>(SB)
16:
17: TEXT ·IndexString(SB),NOSPLIT,$0-40
=> 18: MOVQ a_base+0(FP), DI
19: MOVQ a_len+8(FP), DX
20: MOVQ b_base+16(FP), R8
21: MOVQ b_len+24(FP), AX
22: MOVQ DI, R10
23: LEAQ ret+32(FP), R11
(dlv) bp
Breakpoint runtime-fatal-throw (enabled) at 0x1032e20 for runtime.throw() /Users/qinshixian/.g/go/src/runtime/panic.go:1188 (0)
Breakpoint unrecovered-panic (enabled) at 0x1033180 for runtime.fatalpanic() /Users/qinshixian/.g/go/src/runtime/panic.go:1271 (0)
print runtime.curg._panic.arg
Breakpoint 1 (enabled) at 0x10acd6f for main.main() ./a.go:8 (1)
Breakpoint 2 (enabled) at 0x10ac1e6 for strings.Contains() /Users/qinshixian/.g/go/src/strings/strings.go:61 (0)
(dlv)
//代码效果参考:http://www.mwgw.cn/sitemap/post.xml
3.dlv debug 常用命令
• b 打断点,例如使用 b main.main 来打断点
• p 打印变量
• n: 执行到下一行
• c: 跳过此断点
• args: 打印所有的方法参数
• locals 打印出所有的本地变量
• l 列出断点最近几行的代码
• bp: 展示出所有的断点
• q: 退出

相关文章
|
6月前
|
算法 Unix Linux
【C/C++ 实用工具】性能分析工具一览
【C/C++ 实用工具】性能分析工具一览
297 0
|
6月前
|
小程序 IDE API
8月开发者日回顾|小程序开发实用工具分享
8月开发者日回顾|小程序开发实用工具分享
48 0
|
存储 监控 算法
代码调试技巧
代码调试技巧
|
IDE Java 网络安全
本地 IDE 开发代码方式|学习笔记
快速学习本地 IDE 开发代码方式
本地 IDE 开发代码方式|学习笔记
|
消息中间件 存储 JSON
源码环境调试|学习笔记
快速学习源码环境调试
源码环境调试|学习笔记
|
Java 开发者
menubar小工具 | 学习笔记
快速学习menubar小工具
121 0
|
前端开发 IDE Java
开发工具介绍|学习笔记
快速学习开发工具介绍
|
Web App开发 存储 IDE
5分钟学会制作自动化脚本——自动化脚本辅助开发IDE——Selenium IDE介绍(测试工程师必备)
本文介绍了自动化测试的辅助工具,Selenium IDE的基本使用,有助于自动化工程师辅助编辑自动化脚本,初步建立简单自动化脚本。
432 0
5分钟学会制作自动化脚本——自动化脚本辅助开发IDE——Selenium IDE介绍(测试工程师必备)
|
运维 Kubernetes Go
|
NoSQL Linux
自己动手开发调试器 01
背景:     在做XXX编译器检证时经常需要区分是代码端错误,还是编译器端错误,因此对代码进行调试是必不可少的。但是狗日的甲方并没有提供对应的调试器XXXDB,而用GDB调试XXX生成的可执行程序很不稳定,经常出现异常,干脆自己动手,写mini调试器,顺便学习一下开发一个调试器到底需要哪些知识。
1211 0