GO debug - delve
2021-01-05 本文已影响0人
markfork
大纲
- 简介
- 演示
- 多 goroutine 调试
- core 调试
- 线上 调试
1 简介
1.1 delve 特性
- 是 GO 语言调试器;
- 该调试器 简单、功能齐全、易用使用、调用,是GO调试器的事实标准;
- 支持并发调试、跨平台;
2 演示
2.1 下载delve
go get github.com/go-delve/delve/cmd/dlv
2.2 常用调试命令
以下为用来演示的被调试代码, 对应代码结构
、内容
如下所示:
代码结构:
├── 2021_01_04
│ └── foo.go
├── README.md
├── go.mod
├── go.sum
├── main.go
代码内容:
// main.go
package main
import (
foo "distribute_arch/2021_01_04"
"fmt"
)
func main() {
//var mtx sync.Mutex
//var shareVal = 10
//for {
// go func() {
// mtx.Lock()
// defer mtx.Unlock()
// shareVal--
// }()
//}
// dlv practice
20 a := 3
21 b := 10
22 c := foo.Foo(a, b)
23 fmt.Printf("c | %d", c)
}
// foo.go
1 package foo
2
3 func Foo(step, count int) int {
4 sum := 0
5 for i := 0; i < count; i++ {
6 sum += step
7 }
8 return sum
9 }
2.3 启动delve

语法
: dlv debug [程序主入口]
效果
: 会在主入口程序同级的地方生成 __debug_bin 文件;
2.4 设置断点

语法
: b [断点名称] [文件名:行号]
2.5 查看断点
bp 即 breakpoint
效果
:

2.6 运行程序至断点处
c 即 continue
效果
:

2.7 打印变量
- locals
- p
效果
:
打印本地变量
2.8 设置变量
set variable = xxx
效果
:

2.9 重新运行
r
效果
:

2.10 清除断点
clear [bp index]
效果
:

如图所示,删除次序断点;
2.11 栈帧间跳转
通过 up
和 down
命令,我们可以在函数调用栈的栈帧间进行跳转,如下图所示:

2.12 设置条件断点
语法
: cond [bpname] 条件
效果
:

即 当满足上述条件时 sum > 10 时,断点生效;
2.13 单步执行 next、 step
都是单步执行,不过next 是执行到断点处的下一行,step 在遇到断点处有函数调用,会进入到函数体内;
3 多 goroutine 调试
与普通模式下的调试无太大差异,我们可以将断点打到 goroutine 部分;
被调试代码:
// main.go
package main
import (
foo "distribute_arch/2021_01_04"
bar "distribute_arch/2021_01_05"
"fmt"
"sync"
"time"
)
func main() {
//var mtx sync.Mutex
//var shareVal = 10
//for {
// go func() {
// mtx.Lock()
// defer mtx.Unlock()
// shareVal--
// }()
//}
// dlv practice - common model
//a := 3
//b := 10
//c := foo.Foo(a, b)
//fmt.Printf("c | %d", c)
// dlv practice - goroutine model
var wg sync.WaitGroup
wg.Add(1)
go func() {
for {
d := 2
e := 20
f := bar.Bar(d, e)
fmt.Println(f)
time.Sleep(2 * time.Second)
}
wg.Done()
}()
a := 3
b := 10
c := foo.Foo(a, b)
fmt.Println(c)
wg.Wait()
fmt.Println("program exit")
}
// bar.go
package bar
func Bar(step, count int) int {
sum := 1
for i := 0; i < count; i++ {
sum *= step
}
return sum
}
在 f := bar.Bar(d, e)
处打上断点,

结合 goroutine 和 goroutines 在 多个协程中间践行跳转;

多练;