All Articles

Golang Debug

1. 前言

本文是Go语言系列文章Golang Notes的其中一篇,完整的文章列表请去总章查看。

Go语言的Debug工具对于一直写高级语言的程序员来说有点陌生,而对于写C常年和GDB打交道的程序员来说,则非常熟悉。

2. 安装

MAC下的官方安装教程:Installation on OSX

环境完备的情况下只要直接使用go的下载命令即可:

$ go get -u github.com/go-delve/delve/cmd/dlv

如果没有设置过$GOPATH的话,软件包会安装在~/go下。然后需要把~/go/bin加入到$PATH里,就可以全局使用这个debug工具了。

MAC下使用的时候可能遇到如下问题:

$ dlv debug goroutine.go
could not launch process: debugserver or lldb-server not found: install XCode's command line tools or lldb-server

需要重新安装xcode的命令行工具:

$ xcode-select --install

完成后即可正常使用:

$ dlv debug goroutine.go
Type 'help' for list of commands.
(dlv)

2. 使用

dlv可以以两种模式进行运行:

  • API模式:
    • 暴露API接口,提供给其他IDE等工具,提供协同Debug的能力
    • 此外也可以使用这个模式进行远程debug
    • 文档入口在:delve/Documentation/api/README.md
  • CLI模式:

3. CLI

命令行下使用dlv首先需要了解dlv这个命令本身的使用方法:dlv help

  • attach:附到一个正在运行的线程上,这个在生产环境上比较常见
  • connect:把自己作为客户端,连接到远程debug进程上
  • core:检查一个核心导出文件(core dump)
  • debug:从源代码开编译,并debug
  • exec:运行并debug一个已经编译完成的二进制文件
  • test:编译一个test二进制文件,并进行debug
  • trace:编译并对程序进行trace

在线的文档可以在github上看到:delve/Documentation/usage/dlv.md。类似debug、exec等,在这个主页面里都可以看得到,不过打开也没什么细节,就是一些选项参数的说明,和$ dlv connect ...打印出来的没差别。

经过上面的选择后,就可以进入到dlv的交互界面了,同样的,可以通过(dlv) help来查看交互命令选项。

在调试过程中,有些时候你需要做一些细节观察行为,比如说打印出某些变量的值之类的。dlv提供了一些go语法的子集表达式,可以在交互界面直接使用:Expressions

实际的debug范例可以看这篇:使用Delve进行Golang代码的调试,算是讲解得很贴近日常工作使用了。

资料

dlv help {#ID_APP_HELP}

$ dlv help
Delve is a source level debugger for Go programs.

Delve enables you to interact with your program by controlling the execution of the process,
evaluating variables, and providing information of thread / goroutine state, CPU register state and more.

The goal of this tool is to provide a simple yet powerful interface for debugging Go programs.

Pass flags to the program you are debugging using `--`, for example:

`dlv exec ./hello -- server --config conf/config.toml`

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. Note that the server API is not reentrant and clients will have to coordinate.
      --api-version int      Selects API version when headless. (default 1)
      --backend string       Backend selection:
	default		Uses lldb on macOS, native everywhere else.
	native		Native backend.
	lldb		Uses lldb-server or debugserver.
	rr		Uses mozilla rr (https://github.com/mozilla/rr).
 (default "default")
      --build-flags string   Build flags, to be passed to the compiler.
      --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 "localhost:0")
      --log                  Enable debugging server logging.
      --log-output string    Comma separated list of components that should produce debug output, possible values:
	debugger	Log debugger commands
	gdbwire		Log connection to gdbserial backend
	lldbout		Copy output from debugserver/lldb to standard output
	debuglineerr	Log recoverable errors reading .debug_line
	rpc		Log all RPC messages
	fncall		Log function call protocol
	minidump	Log minidump loading
Defaults to "debugger" when logging is enabled with --log.
      --wd string            Working directory for running the program. (default ".")

Use "dlv [command] --help" for more information about a command.

(dlv) help {#ID_APP_DLV_HELP}

(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 ------------------- Shows or changes current goroutine
    goroutines ------------------ List program goroutines.
    help (alias: h) ------------- Prints the help message.
    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 --------------------- 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.

EOF

Published 2019/3/27

Some tech & personal blog posts