GO debug - delve

2021-01-05  本文已影响0人  markfork

大纲

1 简介

1.1 delve 特性

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

开启delve
语法: dlv debug [程序主入口]

效果: 会在主入口程序同级的地方生成 __debug_bin 文件;

2.4 设置断点

设置断点
语法: b [断点名称] [文件名:行号]

2.5 查看断点

bp 即 breakpoint
效果:

断点列表

2.6 运行程序至断点处

c 即 continue
效果:

程序在第一个断点处停下

2.7 打印变量

2.8 设置变量

set variable = xxx
效果:

效果

2.9 重新运行

r
效果:

restart

2.10 清除断点

clear [bp index]
效果:

clear 断点
如图所示,删除次序断点;

2.11 栈帧间跳转

通过 updown 命令,我们可以在函数调用栈的栈帧间进行跳转,如下图所示:

栈帧间跳转

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 在 多个协程中间践行跳转;


goroutines

多练;

上一篇 下一篇

猜你喜欢

热点阅读