使用delve 调试golang程序


目录


运行编译程序,并且指定参数

  • 使用 -- 用于指定命令行参数
  • 等同于指定命令 bin/go_build_main_go ckfpp -c 10240000
[going@dev cuckoohui]$ dlv exec bin/go_build_main_go -- ckfpp -c 10240000
Type 'help' for list of commands.

在开始的main函数添加断点

(dlv) b main.main
Breakpoint 1 (enabled) set at 0x605813 for main.main() ./main.go:12

查询函数,并且添加断点

(dlv) funcs cuckoo
cuckoohui/commands.(*CuckooCommand).Main
cuckoohui/commands.(*CuckooFppCommand).Main
cuckoohui/commands.(*HelloCommand).Main
cuckoohui/commands.(*HuiHelloCommand).Main
cuckoohui/configor.init.0
cuckoohui/di.init.0
cuckoohui/di.init.0.func1
cuckoohui/di.init.0.func1.1
cuckoohui/dotenv.init.0
github.com/seiflotfy/cuckoofilter.(*Filter).Count
github.com/seiflotfy/cuckoofilter.(*Filter).Delete
github.com/seiflotfy/cuckoofilter.(*Filter).Insert
github.com/seiflotfy/cuckoofilter.(*Filter).InsertUnique
github.com/seiflotfy/cuckoofilter.(*Filter).Lookup
github.com/seiflotfy/cuckoofilter.(*Filter).Reset
github.com/seiflotfy/cuckoofilter.(*Filter).delete
github.com/seiflotfy/cuckoofilter.(*Filter).insert
github.com/seiflotfy/cuckoofilter.(*Filter).reinsert
github.com/seiflotfy/cuckoofilter.(*bucket).delete
github.com/seiflotfy/cuckoofilter.(*bucket).getFingerprintIndex
github.com/seiflotfy/cuckoofilter.(*bucket).insert
github.com/seiflotfy/cuckoofilter.(*bucket).reset
github.com/seiflotfy/cuckoofilter.NewFilter
github.com/seiflotfy/cuckoofilter.getAltIndex
github.com/seiflotfy/cuckoofilter.getFingerprint
github.com/seiflotfy/cuckoofilter.getIndexAndFingerprint
github.com/seiflotfy/cuckoofilter.getNextPow2
github.com/seiflotfy/cuckoofilter.init.0
github.com/seiflotfy/cuckoofilter.randi
(dlv) b cuckoohui/commands.(*CuckooFppCommand).Main
Breakpoint 2 (enabled) set at 0x51c21b for cuckoohui/commands.(*CuckooFppCommand).Main() ./commands/cuckoo.go:43

使用continue 继续运行程序,使用n 步进

(dlv) continue
> main.main() ./main.go:12 (hits goroutine(1):1 total:1) (PC: 0x605813)
Warning: debugging optimized function
     7:         _ "cuckoohui/dotenv"
     8:         "github.com/mix-go/dotenv"
     9:         "github.com/mix-go/xcli"
    10: )
    11:
=>  12: func main() {
    13:         xcli.SetName("app").
    14:                 SetVersion("0.0.0-alpha").
    15:                 SetDebug(dotenv.Getenv("APP_DEBUG").Bool(false))
    16:         xcli.AddCommand(commands.Commands...).Run()
    17: }


(dlv) n 5
> cuckoohui/commands.(*CuckooFppCommand).Main() ./commands/cuckoo.go:43 (hits goroutine(1):1 total:1) (PC: 0x51c21b)
Warning: debugging optimized function
    38: }
    39:
    40: type CuckooFppCommand struct {
    41: }
    42:
=>  43: func (t *CuckooFppCommand) Main() {
    44:         count := flag.Match("c", "count").Int64(1024)
    45:         fpp := flag.Match("f", "fpp").Float64(0.01)
    46:
    47:         cf := cuckoo.NewFilter(uint(count))
    48:         fmt.Printf("cuckoo cap : %d, fpp : %f\n", count, fpp)
(dlv) n
> cuckoohui/commands.(*CuckooFppCommand).Main() ./commands/cuckoo.go:44 (PC: 0x51c232)
Warning: debugging optimized function
    39:
    40: type CuckooFppCommand struct {
    41: }
    42:
    43: func (t *CuckooFppCommand) Main() {
=>  44:         count := flag.Match("c", "count").Int64(1024)
    45:         fpp := flag.Match("f", "fpp").Float64(0.01)
    46:
    47:         cf := cuckoo.NewFilter(uint(count))
    48:         fmt.Printf("cuckoo cap : %d, fpp : %f\n", count, fpp)
    49:
(dlv) n
> cuckoohui/commands.(*CuckooFppCommand).Main() ./commands/cuckoo.go:45 (PC: 0x51c358)
Warning: debugging optimized function
    40: type CuckooFppCommand struct {
    41: }
    42:
    43: func (t *CuckooFppCommand) Main() {
    44:         count := flag.Match("c", "count").Int64(1024)
=>  45:         fpp := flag.Match("f", "fpp").Float64(0.01)
    46:
    47:         cf := cuckoo.NewFilter(uint(count))
    48:         fmt.Printf("cuckoo cap : %d, fpp : %f\n", count, fpp)
    49:
    50:         iCount := 0

打印变量

(dlv) locals
count = 10240000
(dlv) print buf
(unreadable read out of bounds)
(dlv) locals
count = 10240000
fpp = 0.01
cf = (unreadable empty OP stack)
iCount = 0
buf = (unreadable read out of bounds)
i = 0
(dlv) n
> cuckoohui/commands.(*CuckooFppCommand).Main() ./commands/cuckoo.go:56 (PC: 0x51c5bf)
Warning: debugging optimized function
    51:
    52:         buf := make([]byte, 16)
    53:         for i := 0; i < int(count); i++ {
    54:                 rand.Read(buf)
    55:
=>  56:                 iSuccess := cf.InsertUnique(buf)
    57:                 if iSuccess {
    58:                         iCount++
    59:                 }
    60:         }
    61:
(dlv) buf
Command failed: command not available
(dlv) locals
count = 10240000
fpp = 0.01
cf = (unreadable empty OP stack)
iCount = 0
buf = []uint8 len: 824633802688, cap: 140725236128952, [...]
i = 0
(dlv) print buf
[]uint8 len: 824633802688, cap: 140725236128952, [251,22,63,226,157,174,90,125,18,85,77,146,190,80,18,250,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...+824633802624 more]
(dlv) quit

step 进入函数调用内部 stepout 跳出函数调用

(dlv) n
> cuckoohui/commands.(*CuckooFppCommand).Main() ./commands/cuckoo.go:56 (PC: 0x51c5ad)
Warning: debugging optimized function
    51:
    52:         buf := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
    53:         for i := 0; i < int(count); i++ {
    54:                 rand.Read(buf)
    55:
=>  56:                 iSuccess := cf.InsertUnique(buf)
    57:                 if iSuccess {
    58:                         iCount++
    59:                 }
    60:         }
    61:
(dlv) step #进入cf.InsertUnique(buf)
> github.com/seiflotfy/cuckoofilter.(*Filter).InsertUnique() /home/going/workspace/golang/pkg/mod/github.com/seiflotfy/cuckoofilter@v0.0.0-20201222105146-bc6005554a0c/cuckoofilter.go:73 (PC: 0x5180d3)
Warning: debugging optimized function
    68:         }
    69:         return cf.reinsert(fp, randi(i1, i2))
    70: }
    71:
    72: // InsertUnique inserts data into the counter if not exists and returns true upon success
=>  73: func (cf *Filter) InsertUnique(data []byte) bool {
    74:         if cf.Lookup(data) {
    75:                 return false
    76:         }
    77:         return cf.Insert(data)
    78: }
(dlv) n
> github.com/seiflotfy/cuckoofilter.(*Filter).InsertUnique() /home/going/workspace/golang/pkg/mod/github.com/seiflotfy/cuckoofilter@v0.0.0-20201222105146-bc6005554a0c/cuckoofilter.go:74 (PC: 0x5180e1)
Warning: debugging optimized function
    69:         return cf.reinsert(fp, randi(i1, i2))
    70: }
    71:
    72: // InsertUnique inserts data into the counter if not exists and returns true upon success
    73: func (cf *Filter) InsertUnique(data []byte) bool {
=>  74:         if cf.Lookup(data) {
    75:                 return false
    76:         }
    77:         return cf.Insert(data)
    78: }
    79:
(dlv) step #进入cf.Lookup(data)
> github.com/seiflotfy/cuckoofilter.(*Filter).Lookup() /home/going/workspace/golang/pkg/mod/github.com/seiflotfy/cuckoofilter@v0.0.0-20201222105146-bc6005554a0c/cuckoofilter.go:35 (PC: 0x517d33)
Warning: debugging optimized function
    30:                 bucketPow: uint(bits.TrailingZeros(capacity)),
    31:         }
    32: }
    33:
    34: // Lookup returns true if data is in the counter
=>  35: func (cf *Filter) Lookup(data []byte) bool {
    36:         i1, fp := getIndexAndFingerprint(data, cf.bucketPow)
    37:         if cf.buckets[i1].getFingerprintIndex(fp) > -1 {
    38:                 return true
    39:         }
    40:         i2 := getAltIndex(fp, i1, cf.bucketPow)
(dlv) n
> github.com/seiflotfy/cuckoofilter.(*Filter).Lookup() /home/going/workspace/golang/pkg/mod/github.com/seiflotfy/cuckoofilter@v0.0.0-20201222105146-bc6005554a0c/cuckoofilter.go:36 (PC: 0x517d41)
Warning: debugging optimized function
    31:         }
    32: }
    33:
    34: // Lookup returns true if data is in the counter
    35: func (cf *Filter) Lookup(data []byte) bool {
=>  36:         i1, fp := getIndexAndFingerprint(data, cf.bucketPow)
    37:         if cf.buckets[i1].getFingerprintIndex(fp) > -1 {
    38:                 return true
    39:         }
    40:         i2 := getAltIndex(fp, i1, cf.bucketPow)
    41:         return cf.buckets[i2].getFingerprintIndex(fp) > -1
(dlv) stepout #退出函数调用
> github.com/seiflotfy/cuckoofilter.(*Filter).InsertUnique() /home/going/workspace/golang/pkg/mod/github.com/seiflotfy/cuckoofilter@v0.0.0-20201222105146-bc6005554a0c/cuckoofilter.go:74 (PC: 0x51810d)
Warning: debugging optimized function
Values returned:
        ~r1: (unreadable empty OP stack)

    69:         return cf.reinsert(fp, randi(i1, i2))
    70: }
    71:
    72: // InsertUnique inserts data into the counter if not exists and returns true upon success
    73: func (cf *Filter) InsertUnique(data []byte) bool {
=>  74:         if cf.Lookup(data) {
    75:                 return false
    76:         }
    77:         return cf.Insert(data)
    78: }
    79:
(dlv) stepout
> cuckoohui/commands.(*CuckooFppCommand).Main() ./commands/cuckoo.go:56 (PC: 0x51c5dd)
Warning: debugging optimized function
Values returned:
        ~r1: (unreadable empty OP stack)

    51:
    52:         buf := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
    53:         for i := 0; i < int(count); i++ {
    54:                 rand.Read(buf)
    55:
=>  56:                 iSuccess := cf.InsertUnique(buf)
    57:                 if iSuccess {
    58:                         iCount++
    59:                 }
    60:         }
    61:
(dlv)

NOTE

centos yum 源的delve 可能版本比较低, 无法调试go 1.16.
可以选择卸载了, 然后通过go 安装.可以选择一下两种方式:

  1. Clone the git repository and build:

git clone https://github.com/go-delve/delve
cd delve
go install github.com/go-delve/delve/cmd/dlv

  1. On Go version 1.16 or later, this command will also work:

go install github.com/go-delve/delve/cmd/dlv@latest

教程


Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: