golang单步调试神器delve

北二条 · · 1004 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

写在前面

上节我写了个bug,粗心大意肉眼没看出来,所以我们祭出golang的单步调试神器delve来帮我解决问题。
Delve也是单步执行工具,和GDB很像,但是他更方便安装,本身也是go的包之一,安装方法如下:

#设置代理
export https_proxy=socks5://192.168.88.1:1080
export http_proxy=socks5://192.168.88.1:1080

#安装dlv
go get -u -v  github.com/go-delve/delve/cmd/dlv

dlv帮助:

[root@localhost tail]# dlv -h
Usage:
  dlv [command]

Available Commands:
  attach      Attach to running process and begin debugging.
  connect     Connect to a headless debug server.
  core        Examine a core dump.
  debug       Compile and begin debugging main package in current directory, or the package specified.
  exec        Execute a precompiled binary, and begin a debug session.
  help        Help about any command
  run         Deprecated command. Use 'debug' instead.
  test        Compile test binary and begin debugging program.
  trace       Compile and begin tracing program.
  version     Prints version.

Flags:
      --accept-multiclient   Allows a headless server to accept multiple client connections.
      --api-version int      Selects API version when headless. (default 1)
      --backend string       Backend selection (see 'dlv help backend'). (default "default")
      --build-flags string   Build flags, to be passed to the compiler.
      --check-go-version     Checks that the version of Go in use is compatible with Delve. (default true)
      --headless             Run debug server only, in headless mode.
      --init string          Init file, executed by the terminal client.
  -l, --listen string        Debugging server listen address. (default "127.0.0.1:0")
      --log                  Enable debugging server logging.
      --log-dest string      Writes logs to the specified file or file descriptor (see 'dlv help log').
      --log-output string    Comma separated list of components that should produce debug output (see 'dlv help log')
      --wd string            Working directory for running the program. (default ".")

Additional help topics:
  dlv backend Help about the --backend flag.
  dlv log     Help about logging flags

帮助写的很详细,比较常用的是debug执行go文件,和attach pid。
然后我们执行dlv debug wscat.go,添加参数的话,用“--”两个横线来表示

[root@localhost tail]# dlv debug wscat.go -- ws://127.0.0.1:8888/watch/clusterlog?clusterid=cb63a0bc-8273-45ef-a966-67b46968e518  http://127.0.0.1:8888
Type 'help' for list of commands.
(dlv) help
The following commands are available:
    args ------------------------ Print function arguments.
    break (alias: b) ------------ Sets a breakpoint.
    breakpoints (alias: bp) ----- Print out info for active breakpoints.
    call ------------------------ Resumes process, injecting a function call (EXPERIMENTAL!!!)
    clear ----------------------- Deletes breakpoint.
    clearall -------------------- Deletes multiple breakpoints.
    condition (alias: cond) ----- Set breakpoint condition.
    config ---------------------- Changes configuration parameters.
    continue (alias: c) --------- Run until breakpoint or program termination.
    deferred -------------------- Executes command in the context of a deferred call.
    disassemble (alias: disass) - Disassembler.
    down ------------------------ Move the current frame down.
    edit (alias: ed) ------------ Open where you are in $DELVE_EDITOR or $EDITOR
    exit (alias: quit | q) ------ Exit the debugger.
    frame ----------------------- Set the current frame, or execute command on a different frame.
    funcs ----------------------- Print list of functions.
    goroutine (alias: gr) ------- Shows or changes current goroutine
    goroutines (alias: grs) ----- List program goroutines.
    help (alias: h) ------------- Prints the help message.
    libraries ------------------- List loaded dynamic libraries
    list (alias: ls | l) -------- Show source code.
    locals ---------------------- Print local variables.
    next (alias: n) ------------- Step over to next source line.
    on -------------------------- Executes a command when a breakpoint is hit.
    print (alias: p) ------------ Evaluate an expression.
    regs ------------------------ Print contents of CPU registers.
    restart (alias: r) ---------- Restart process.
    set ------------------------- Changes the value of a variable.
    source ---------------------- Executes a file containing a list of delve commands
    sources --------------------- Print list of source files.
    stack (alias: bt) ----------- Print stack trace.
    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.
    thread (alias: tr) ---------- Switch to the specified thread.
    threads --------------------- Print out info for every traced thread.
    trace (alias: t) ------------ Set tracepoint.
    types ----------------------- Print list of types
    up -------------------------- Move the current frame up.
    vars ------------------------ Print package variables.
    whatis ---------------------- Prints type of an expression.
Type help followed by a command for full documentation.

都是一些常用的命令,首先为main函数打个断点

(dlv) b main.main
Breakpoint 1 set at 0x7041cb for main.main() ./wscat.go:20

也可以通过行号来打断点:

(dlv) b wscat.go:20
Breakpoint 1 set at 0x7041cb for main.main() ./wscat.go:20

两者是一样的,接下来我们执行c: continue执行到main函数

[root@localhost tail]# dlv debug wscat.go -- ws://127.0.0.1:8888/watch/clusterlog?clusterid=cb63a0bc-8273-45ef-a966-67b46968e518  http://127.0.0.1:8888
Type 'help' for list of commands.
(dlv) b wscat.go:32
Breakpoint 1 set at 0x704711 for main.main.func1() ./wscat.go:32
(dlv) c
Dial url: ws://127.0.0.1:8888/watch/clusterlog?clusterid=cb63a0bc-8273-45ef-a966-67b46968e518 ,origin: http://127.0.0.1:8888
> main.main.func1() ./wscat.go:32 (hits goroutine(7):1 total:1) (PC: 0x704711)
    27:     }
    28: 
    29:     var msg = make([]byte, 512)
    30:     go func() {
    31:         for {
=>  32:             ws.Read(msg)
    33:             m, err := ws.Read(msg)
    34:             if err != nil {
    35:                 log.Fatal(err)
    36:             }
    37:             fmt.Printf("Receive: %s\n", msg[:m])
(dlv) 

b 打断点到32行
n 是执行下一步
s 是执行step
p 是打印
set 是设置变量
然后发现了代码的出错地方:
ws.Read调用了两遍:

    31:         for {
=>  32:             ws.Read(msg)
    33:             m, err := ws.Read(msg)
    34:             if err != nil {

dlv很好用,大家动手用一下就了解了。
以上↑


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:北二条

查看原文:golang单步调试神器delve

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1004 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传