前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >go语言调试工具--Delve

go语言调试工具--Delve

作者头像
DBA札记
发布2022-08-16 14:01:12
3900
发布2022-08-16 14:01:12
举报
文章被收录于专栏:MySQL参数系列

测试代码片段

代码语言:javascript
复制
package main


import (
    "fmt"
)


func main() {
    nums := make([]int, 5)
    for i := 0; i < len(nums); i++ {
        nums[i] = i * i
    }
    fmt.Println(nums)
}

进入调试模式

代码语言:javascript
复制
corollad@MacBook-Pro go_dlv % dlv debug
Type 'help' for list of commands.
(dlv)
(dlv) help
The following commands are available:


Running the program:
    call ------------------------ Resumes process, injecting a function call (EXPERIMENTAL!!!)
    continue (alias: c) --------- Run until breakpoint or program termination.
    next (alias: n) ------------- Step over to next source line.
    rebuild --------------------- Rebuild the target executable and restarts it. It does not work if the executable was not built by delve.
    restart (alias: r) ---------- Restart process.
    step (alias: s) ------------- Single step through program.
    step-instruction (alias: si)  Single step a single cpu instruction.
    stepout (alias: so) --------- Step out of the current function.


Manipulating breakpoints:
    break (alias: b) ------- Sets a breakpoint.
    breakpoints (alias: bp)  Print out info for active breakpoints.
    clear ------------------ Deletes breakpoint.
    clearall --------------- Deletes multiple breakpoints.
    condition (alias: cond)  Set breakpoint condition.
    on --------------------- Executes a command when a breakpoint is hit.
    toggle ----------------- Toggles on or off a breakpoint.
    trace (alias: t) ------- Set tracepoint.
    watch ------------------ Set watchpoint.


Viewing program variables and memory:
    args ----------------- Print function arguments.
    display -------------- Print value of an expression every time the program stops.
    examinemem (alias: x)  Examine raw memory at the given address.
    locals --------------- Print local variables.
    print (alias: p) ----- Evaluate an expression.
    regs ----------------- Print contents of CPU registers.
    set ------------------ Changes the value of a variable.
    vars ----------------- Print package variables.
    whatis --------------- Prints type of an expression.


Listing and switching between threads and goroutines:
    goroutine (alias: gr) -- Shows or changes current goroutine
    goroutines (alias: grs)  List program goroutines.
    thread (alias: tr) ----- Switch to the specified thread.
    threads ---------------- Print out info for every traced thread.


Viewing the call stack and selecting frames:
    deferred --------- Executes command in the context of a deferred call.
    down ------------- Move the current frame down.
    frame ------------ Set the current frame, or execute command on a different frame.
    stack (alias: bt)  Print stack trace.
    up --------------- Move the current frame up.


Other commands:
    config --------------------- Changes configuration parameters.
    disassemble (alias: disass)  Disassembler.
    dump ----------------------- Creates a core dump from the current process state
    edit (alias: ed) ----------- Open where you are in $DELVE_EDITOR or $EDITOR
    exit (alias: quit | q) ----- Exit the debugger.
    funcs ---------------------- Print list of functions.
    help (alias: h) ------------ Prints the help message.
    libraries ------------------ List loaded dynamic libraries
    list (alias: ls | l) ------- Show source code.
    source --------------------- Executes a file containing a list of delve commands
    sources -------------------- Print list of source files.
    types ---------------------- Print list of types


Type help followed by a command for full documentation.

每个Go程序的入口是main.main函数,我们可以用break在此设置一个断点:

代码语言:javascript
复制
(dlv) break main.main
Breakpoint 1 set at 0x10cbbd8 for main.main() ./main.go:7

然后通过breakpoints查看已经设置的所有断点:

代码语言:javascript
复制
(dlv) breakpoints
Breakpoint runtime-fatal-throw (enabled) at 0x1038dc0 for runtime.throw() /usr/local/Cellar/go/1.16.6/libexec/src/runtime/panic.go:1107 (0)
Breakpoint unrecovered-panic (enabled) at 0x1039040 for runtime.fatalpanic() /usr/local/Cellar/go/1.16.6/libexec/src/runtime/panic.go:1190 (0)
       print runtime.curg._panic.arg
Breakpoint 1 (enabled) at 0x10cbbd8 for main.main() ./main.go:7 (0)

除了我们自己设置的main.main函数断点外,Delve内部已经为panic异常函数设置了一个断点。

通过vars命令可以查看全部包级的变量。因为最终的目标程序可能含有大量的全局变量,我们可以通过一个正则参数选择想查看的全局变量:

代码语言:javascript
复制
(dlv) vars main
runtime.main_init_done = chan bool nil
runtime.mainStarted = false

然后就可以通过continue命令让程序运行到下一个断点处:

代码语言:javascript
复制
(dlv) continue
> main.main() ./main.go:7 (hits goroutine(1):1 total:1) (PC: 0x10cbbd8)
     2:
     3:       import (
     4:           "fmt"
     5:       )
     6:
=>   7:       func main() {
     8:           nums := make([]int, 5)
     9:           for i := 0; i < len(nums); i++ {
    10:               nums[i] = i * i
    11:           }
    12:           fmt.Println(nums)

输入next命令单步执行进入main函数内部:

代码语言:javascript
复制
(dlv) next
> main.main() ./main.go:8 (PC: 0x10cbbef)
     3:       import (
     4:           "fmt"
     5:       )
     6:
     7:       func main() {
=>   8:           nums := make([]int, 5)
     9:           for i := 0; i < len(nums); i++ {
    10:               nums[i] = i * i
    11:           }
    12:           fmt.Println(nums)
    13:       }

进入函数之后可以通过argslocals命令查看函数的参数和局部变量:

代码语言:javascript
复制
(dlv) args
(no args)
(dlv) locals
nums = []int len: 5, cap: 5, [...]

再次输入next命令单步执行后就可以查看到nums切片初始化之后的结果了:

代码语言:javascript
复制
(dlv) next
> main.main() ./main.go:10 (PC: 0x10cbc4b)
     5:       )
     6:
     7:       func main() {
     8:           nums := make([]int, 5)
     9:           for i := 0; i < len(nums); i++ {
=>  10:               nums[i] = i * i
    11:           }
    12:           fmt.Println(nums)
    13:       }
(dlv) locals
nums = []int len: 5, cap: 5, [...]
i = 0

下面我们通过组合使用breakcondition命令,在循环内部设置一个条件断点,当循环变量i等于3时断点生效:

代码语言:javascript
复制
(dlv) break main.go:10
Breakpoint 2 set at 0x10cbc4b for main.main() ./main.go:10
(dlv) condition 2 i==3
(dlv)

然后通过continue执行到刚设置的条件断点,并且输出局部变量:

代码语言:javascript
复制
(dlv) continue
> main.main() ./main.go:10 (hits goroutine(1):1 total:1) (PC: 0x10cbc4b)
     5:       )
     6:
     7:       func main() {
     8:           nums := make([]int, 5)
     9:           for i := 0; i < len(nums); i++ {
=>  10:               nums[i] = i * i
    11:           }
    12:           fmt.Println(nums)
    13:       }
(dlv) locals
nums = []int len: 5, cap: 5, [...]
i = 3
(dlv) print nums
[]int len: 5, cap: 5, [0,1,4,0,0]

我们还可以通过stack查看当前执行函数的栈帧信息:

代码语言:javascript
复制
(dlv) stack
0  0x00000000010cbc4b in main.main
   at ./main.go:10
1  0x000000000103b6e3 in runtime.main
   at /usr/local/Cellar/go/1.16.6/libexec/src/runtime/proc.go:225
2  0x000000000106eba1 in runtime.goexit
   at /usr/local/Cellar/go/1.16.6/libexec/src/runtime/asm_amd64.s:1371

或者通过goroutinegoroutines命令查看当前Goroutine相关的信息:

代码语言:javascript
复制
(dlv) goroutine
Thread 158218 at ./main.go:10
Goroutine 1:
       Runtime: ./main.go:10 main.main (0x10cbc4b)
       User: ./main.go:10 main.main (0x10cbc4b)
       Go: /usr/local/Cellar/go/1.16.6/libexec/src/runtime/asm_amd64.s:226 runtime.rt0_go (0x106cd96)
       Start: /usr/local/Cellar/go/1.16.6/libexec/src/runtime/proc.go:115 runtime.main (0x103b4c0)


(dlv) goroutines
* Goroutine 1 - User: ./main.go:10 main.main (0x10cbc4b) (thread 158218)
  Goroutine 2 - User: /usr/local/Cellar/go/1.16.6/libexec/src/runtime/proc.go:337 runtime.gopark (0x103baf5) [force gc (idle)]
  Goroutine 3 - User: /usr/local/Cellar/go/1.16.6/libexec/src/runtime/proc.go:337 runtime.gopark (0x103baf5) [GC sweep wait]
  Goroutine 4 - User: /usr/local/Cellar/go/1.16.6/libexec/src/runtime/proc.go:337 runtime.gopark (0x103baf5) [GC scavenge wait]
  Goroutine 17 - User: /usr/local/Cellar/go/1.16.6/libexec/src/runtime/proc.go:337 runtime.gopark (0x103baf5) [finalizer wait]
[5 goroutines]

最后完成调试工作后输入quit命令退出调试器。

代码语言:javascript
复制
(dlv) quit
corollad@MacBook-Pro go_dlv %

用到的命令总结:

1、dlv debug

2、break main.main

3、breakpoints

4、vars main

5、continue

6、next

7、args

8、locals

9、break main.go:10 && condition 2 i==3

10、print nums

11、stack

12、goroutine

13、goroutines

14、step(进入函数)

参考资料:《go 语言高级编程》

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-11-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DBA札记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档