携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第5天,点击查看活动详情
安装
mac 安装
brew install github.com/go-delve/delve/delve
如果上面方式不能用使用下面命令:
go install github.com/go-delve/delve/cmd/dlv@latest
windows 安装
go get github.com/derekparker/delve/cmd/dlv
参数说明
| 命令 | 描述 |
|---|---|
| args | 打印函数参数 |
| break | 设置一个断点 |
| breakpoints | 打印激活的断点信息 |
| clear | 删除断点 |
| clearall | 删除所有的断点 |
| condition | 设置断点条件 |
| continue | 运行到断点或程序终止 |
| disassemble | 拆解器 |
| exit | 退出debugger |
| frame | 在不同的框架上执行的命令 |
| funcs | 打印函数列表 |
| goroutine | 显示或更改当前goroutine |
| goroutines | 列出程序的全部goroutines |
| help | 打印出帮助信息 |
| list | 显示源代码 |
| locals | 打印局部变量 |
| next | 跳到下一行 |
| on | 在遇到断点时执行一个命令 |
| 评估表达式 | |
| regs | 打印CPU寄存器的内容 |
| restart | 重启进程 |
| set | 更改变量的值 |
| source | 执行包含delve命令列表的文件 |
| sources | 打印源文件列表 |
| stack | 打印堆栈跟踪 |
| step | 单步执行程序 |
| step-instruction | 单步单个执行cpu指令 |
| thread | 切换到指定的线程 |
| threads | 打印每一个跟踪线程的信息 |
| trace | 设置跟踪点 |
| types | 打印类型列表 |
| vars | 打印某个包内的(全局)变量 |
使用 delve 调试汇编程序
首先写个函数
package main
import (
"fmt"
)
func main() {
printArray()
}
func printArray() {
nums := make([]int, 5)
for i := 0; i < len(nums); i++ {
nums[i] = i * i
}
fmt.Println(nums)
}
在 main.mian 函数打断点,当只想到断点时,可以 使用disassemble 反汇编命令,查看 main 函数对应的汇编代码。
完整使用例子如下:
main git:(master) ✗ dlv debug
Type 'help' for list of commands.
(dlv) break main.main
Breakpoint 1 set at 0x10cb88f for main.main() ./main.go:7
(dlv) continue
> main.main() ./main.go:7 (hits goroutine(1):1 total:1) (PC: 0x10cb88f)
2:
3: import (
4: "fmt"
5: )
6:
=> 7: func main() {
8: //fmt.Println(gobase.Add(1, 2))
9: //hello.Print()
10: //fmt.Println("Hello World")
11: //mysql.Insert()
12:
(dlv) disassemble
TEXT main.main(SB) /Users/bytedance/go/src/code.byted.org/wangmingming.hit/GoProject/main/main.go
main.go:7 0x10cb880 65488b0c2530000000 mov rcx, qword ptr gs:[0x30]
main.go:7 0x10cb889 483b6110 cmp rsp, qword ptr [rcx+0x10]
main.go:7 0x10cb88d 761f jbe 0x10cb8ae
=> main.go:7 0x10cb88f* 4883ec08 sub rsp, 0x8
main.go:7 0x10cb893 48892c24 mov qword ptr [rsp], rbp
main.go:7 0x10cb897 488d2c24 lea rbp, ptr [rsp]
main.go:54 0x10cb89b 0f1f440000 nop dword ptr [rax+rax*1], eax
main.go:54 0x10cb8a0 e81b000000 call $main.printArray
main.go:55 0x10cb8a5 488b2c24 mov rbp, qword ptr [rsp]
main.go:55 0x10cb8a9 4883c408 add rsp, 0x8
main.go:55 0x10cb8ad c3 ret
main.go:7 0x10cb8ae e8ed16faff call $runtime.morestack_noctxt
.:0 0x10cb8b3 ebcb jmp $main.main
函数开头,首先比较 rsp 寄存器,判断栈空间是否充足,如果不充足,则跳转到 0x10cb8ae 调用 $runtime.morestack_noctxt 扩容,跳后跳转到 $main.main 重新进行栈空间测试,在调用 printArray z 之前,扩展 rsp空间,用于存储临时存储 rbp 寄存器,函数返回后恢复 rbp 的只,并收回临时空间。
再打个断点 看看
main git:(master) ✗ dlv debug
Type 'help' for list of commands.
(dlv) break main.printArray
Breakpoint 1 set at 0x10cb8d8 for main.printArray() ./main.go:57
(dlv) continue
> main.printArray() ./main.go:57 (hits goroutine(1):1 total:1) (PC: 0x10cb8d8)
52: //ch <- 10 // 塞一个数
53: //fmt.Println("c", c)
54: printArray()
55: }
56:
=> 57: func printArray() {
58: nums := make([]int, 5)
59: for i := 0; i < len(nums); i++ {
60: nums[i] = i * i
61: }
62: fmt.Println(nums)
(dlv) disassemble
执行结果是 [0 1 4 9 16]
TEXT main.printArray(SB) /Users/bytedance/go/src/code.byted.org/wangmingming.hit/GoProject/main/main.go
main.go:57 0x10cb8c0 65488b0c2530000000 mov rcx, qword ptr gs:[0x30]
main.go:57 0x10cb8c9 488d4424e8 lea rax, ptr [rsp-0x18]
main.go:57 0x10cb8ce 483b4110 cmp rax, qword ptr [rcx+0x10]
main.go:57 0x10cb8d2 0f8675010000 jbe 0x10cba4d
=> main.go:57 0x10cb8d8* 4881ec98000000 sub rsp, 0x98
main.go:57 0x10cb8df 4889ac2490000000 mov qword ptr [rsp+0x90], rbp
main.go:57 0x10cb8e7 488dac2490000000 lea rbp, ptr [rsp+0x90]
main.go:58 0x10cb8ef 488d054aac0000 lea rax, ptr [rip+0xac4a]
main.go:58 0x10cb8f6 48890424 mov qword ptr [rsp], rax
main.go:58 0x10cb8fa 48c744240805000000 mov qword ptr [rsp+0x8], 0x5
main.go:58 0x10cb903 48c744241005000000 mov qword ptr [rsp+0x10], 0x5
main.go:58 0x10cb90c e8ef51f8ff call $runtime.makeslice
main.go:58 0x10cb911 488b442418 mov rax, qword ptr [rsp+0x18]
main.go:58 0x10cb916 4889442460 mov qword ptr [rsp+0x60], rax
main.go:58 0x10cb91b 48c744246805000000 mov qword ptr [rsp+0x68], 0x5
main.go:58 0x10cb924 48c744247005000000 mov qword ptr [rsp+0x70], 0x5
main.go:59 0x10cb92d 48c744243000000000 mov qword ptr [rsp+0x30], 0x0
main.go:59 0x10cb936 eb00 jmp 0x10cb938
main.go:59 0x10cb938 488b542468 mov rdx, qword ptr [rsp+0x68]
main.go:59 0x10cb93d 4889542438 mov qword ptr [rsp+0x38], rdx
main.go:59 0x10cb942 4839542430 cmp qword ptr [rsp+0x30], rdx
main.go:59 0x10cb947 7c02 jl 0x10cb94b
main.go:59 0x10cb949 eb3f jmp 0x10cb98a
main.go:60 0x10cb94b 488b442430 mov rax, qword ptr [rsp+0x30]
main.go:60 0x10cb950 488b4c2468 mov rcx, qword ptr [rsp+0x68]
main.go:60 0x10cb955 488b542460 mov rdx, qword ptr [rsp+0x60]
main.go:60 0x10cb95a 488b5c2430 mov rbx, qword ptr [rsp+0x30]
main.go:60 0x10cb95f 488b742430 mov rsi, qword ptr [rsp+0x30]
main.go:60 0x10cb964 480faff3 imul rsi, rbx
main.go:60 0x10cb968 4839c8 cmp rax, rcx
main.go:60 0x10cb96b 7205 jb 0x10cb972
main.go:60 0x10cb96d e9d5000000 jmp 0x10cba47
main.go:60 0x10cb972 488d14c2 lea rdx, ptr [rdx+rax*8]
main.go:60 0x10cb976 488932 mov qword ptr [rdx], rsi
main.go:60 0x10cb979 eb00 jmp 0x10cb97b
main.go:59 0x10cb97b 488b542430 mov rdx, qword ptr [rsp+0x30]
main.go:59 0x10cb980 48ffc2 inc rdx
main.go:59 0x10cb983 4889542430 mov qword ptr [rsp+0x30], rdx
main.go:59 0x10cb988 ebae jmp 0x10cb938
main.go:62 0x10cb98a 0f57c0 xorps xmm0, xmm0
main.go:62 0x10cb98d 0f11442450 movups xmmword ptr [rsp+0x50], xmm0
main.go:62 0x10cb992 488d442450 lea rax, ptr [rsp+0x50]
main.go:62 0x10cb997 4889442448 mov qword ptr [rsp+0x48], rax
main.go:62 0x10cb99c 488b442460 mov rax, qword ptr [rsp+0x60]
main.go:62 0x10cb9a1 488b4c2468 mov rcx, qword ptr [rsp+0x68]
main.go:62 0x10cb9a6 488b542470 mov rdx, qword ptr [rsp+0x70]
main.go:62 0x10cb9ab 48890424 mov qword ptr [rsp], rax
main.go:62 0x10cb9af 48894c2408 mov qword ptr [rsp+0x8], rcx
main.go:62 0x10cb9b4 4889542410 mov qword ptr [rsp+0x10], rdx
main.go:62 0x10cb9b9 e8a2f5f3ff call $runtime.convTslice
main.go:62 0x10cb9be 488b442418 mov rax, qword ptr [rsp+0x18]
main.go:62 0x10cb9c3 4889442440 mov qword ptr [rsp+0x40], rax
main.go:62 0x10cb9c8 488b4c2448 mov rcx, qword ptr [rsp+0x48]
main.go:62 0x10cb9cd 8401 test byte ptr [rcx], al
main.go:62 0x10cb9cf 488d15ca950000 lea rdx, ptr [rip+0x95ca]
main.go:62 0x10cb9d6 488911 mov qword ptr [rcx], rdx
main.go:62 0x10cb9d9 488d7908 lea rdi, ptr [rcx+0x8]
main.go:62 0x10cb9dd 833d8c5a0d0000 cmp dword ptr [runtime.writeBarrier], 0x0
main.go:62 0x10cb9e4 7402 jz 0x10cb9e8
main.go:62 0x10cb9e6 eb57 jmp 0x10cba3f
main.go:62 0x10cb9e8 48894108 mov qword ptr [rcx+0x8], rax
main.go:62 0x10cb9ec eb00 jmp 0x10cb9ee
main.go:62 0x10cb9ee 488b442448 mov rax, qword ptr [rsp+0x48]
main.go:62 0x10cb9f3 8400 test byte ptr [rax], al
main.go:62 0x10cb9f5 eb00 jmp 0x10cb9f7
main.go:62 0x10cb9f7 4889442478 mov qword ptr [rsp+0x78], rax
main.go:62 0x10cb9fc 48c784248000000001000000 mov qword ptr [rsp+0x80], 0x1
main.go:62 0x10cba08 48c784248800000001000000 mov qword ptr [rsp+0x88], 0x1
main.go:62 0x10cba14 48890424 mov qword ptr [rsp], rax
main.go:62 0x10cba18 48c744240801000000 mov qword ptr [rsp+0x8], 0x1
main.go:62 0x10cba21 48c744241001000000 mov qword ptr [rsp+0x10], 0x1
main.go:62 0x10cba2a e8b19fffff call $fmt.Println
main.go:63 0x10cba2f 488bac2490000000 mov rbp, qword ptr [rsp+0x90]
main.go:63 0x10cba37 4881c498000000 add rsp, 0x98
main.go:63 0x10cba3e c3 ret
main.go:62 0x10cba3f 90 nop
main.go:62 0x10cba40 e8db30faff call $runtime.gcWriteBarrier
main.go:62 0x10cba45 eba7 jmp 0x10cb9ee
main.go:60 0x10cba47 e87435faff call $runtime.panicIndex
main.go:60 0x10cba4c 90 nop
main.go:57 0x10cba4d e84e15faff call $runtime.morestack_noctxt
.:0 0x10cba52 e969feffff jmp $main.printArray
(dlv) regs
Rip = 0x00000000010cb8d8
Rsp = 0x000000c00007df70
Rax = 0x000000c00007df58
Rbx = 0x0000000000000000
Rcx = 0x000000c000000180
Rdx = 0x00000000010f8440
Rsi = 0x0000000000000001
Rdi = 0x000000c000010230
Rbp = 0x000000c00007df78
R8 = 0x0000000000000008
R9 = 0x0000000000000044
R10 = 0x0000000000000020
R11 = 0x0000000000000000
R12 = 0x000000000146140f
R13 = 0x0000000000000000
R14 = 0x0000000000000058
R15 = 0x0000000000000008
Rflags = 0x0000000000000206 [PF IF IOPL=0]
Cs = 0x000000000000002b
Fs = 0x0000000000000000
Gs = 0x0000000000000000