Golang 调试工具 Delve 安装及使用


Golang debug 推荐使用 Delve 工具,项目地址:https://github.com/derekparker/delve

一、安装

照着 github 上 delve 项目的安装说明操作,go mod模式下推荐使用第二种方式。

1. 拉取最新 delve 项目代码到本地,编译安装。

# cd $GOPATH/src/
# git clone https://github.com/derekparker/delve.git
# cd delve/cmd/dlv/
# go build
# go install

国内环境 go build 会报错:

go: golang.org/x/crypto@v0.0.0-20180614174826-fd5f17ee7299: unrecognized import path "golang.org/x/crypto" (https fetch: Get https://golang.org/x/crypto?go-get=1: dial tcp 216.239.37.1:443: i/o timeout)
go: golang.org/x/sys@v0.0.0-20180614134839-8883426083c0: unrecognized import path "golang.org/x/sys" (https fetch: Get https://golang.org/x/sys?go-get=1: dial tcp 216.239.37.1:443: i/o timeout)
go: golang.org/x/arch@v0.0.0-20171004143515-077ac972c2e4: unrecognized import path "golang.org/x/arch" (https fetch: Get https://golang.org/x/arch?go-get=1: dial tcp 216.239.37.1:443: i/o timeout)

原因是 Golang 官网被墙了,这里手动修改go.mod文件,把项目地址替换为 github 上的地址,如:

替换:

golang.org/x/arch v0.0.0-20171004143515-077ac972c2e4 => github.com/golang/arch v0.0.0-20171004143515-077ac972c2e4
        golang.org/x/crypto v0.0.0-20180614174826-fd5f17ee7299 => github.com/golang/crypto v0.0.0-20180614174826-fd5f17ee7299
        golang.org/x/sys v0.0.0-20180614134839-8883426083c0 => github.com/golang/sys v0.0.0-20180614134839-8883426083c0

然后重新编译安装,没有报错则成功。

2. 添加$GOPATH/bin到环境变量,执行dlv命令,查看:

$ dlv
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.
  dap         [EXPERIMENTAL] Starts a TCP server communicating via Debug Adaptor Protocol (DAP).
  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')
      --only-same-user       Only connections from the same user that started this instance of Delve are allowed to connect. (default true)
      --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.

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

二、使用 Delve 调试程序

1. 查看 Delve 支持命令:dlvdlv --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.
    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.
    disassemble (alias: disass) - Disassembler.
    down ------------------------ Move the current frame down.
    exit (alias: quit | q) ------ Exit the debugger.
    frame ----------------------- Set the current frame, or execute command...
    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...
    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.
(dlv)

2. 查询单个命令详情,dlv [command] --help,如:dlv debug --help

$ dlv debug --help
Compiles your program with optimizations disabled, starts and attaches to it.

By default, with no arguments, Delve will compile the 'main' package in the
current directory, and begin to debug it. Alternatively you can specify a
package name and Delve will compile that package instead, and begin a new debug
session.

Usage:
  dlv debug [package] [flags]

Flags:
      --continue        Continue the debugged process on start.
      --output string   Output path for the binary. (default "./__debug_bin")
      --tty string      TTY to use for the target program

Global 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')
      --only-same-user       Only connections from the same user that started this instance of Delve are allowed to connect. (default true)
      --wd string            Working directory for running the program. (default ".")

3. 调试程序

手动创建一个defer项目,defer.go 里面加一些信息,如:

package main

import (
	"log"
)

var first = "panic in defer"
var second = "panic in main"

func main() {
	 defer func() {
		 for {
			 if err := recover(); err != nil {
				 log.Println(err)
			 }else{
				 log.Fatalln("fatal")
			 }
		 }
	 }()
	 defer func() {
	 	panic(first)
	 }()
	 panic(second)
}

通过 dlv debug defer.go 命令进入调试:

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

在入口函数打断点 命令为break(简:b),或在指定行打断点:b main.go:10

(dlv) b main.main
Breakpoint 1 set at 0x10ae9b8 for main.main() ./main.go:10

查看设置好的断点 breakpoints(简:bp)

(dlv) bp
Breakpoint runtime-fatal-throw at 0x437ef0 for runtime.fatalthrow() c:/go/src/runtime/panic.go:1162 (0)
Breakpoint unrecovered-panic at 0x437f70 for runtime.fatalpanic() c:/go/src/runtime/panic.go:1189 (0)
        print runtime.curg._panic.arg
Breakpoint 1 at 0x4cdaff for main.main() C:/Users/y30002195/Desktop/已完成/0.总结文档/go/ch1/4_delve/defer.go:10 (0)

可以看到除了我们手动打的断点,Go 还自动帮我们打了 fatal 异常的两个断点

vars 命令可以查看全部包级的变量:

(dlv) vars main
runtime.main_init_done = chan bool nil
runtime.mainStarted = false
main.second = "panic in main"
main.first = "panic in defer"

让程序运行到下一个断点处 命令为continue(简:c)

> main.main() C:/Users/y30002195/Desktop/已完成/0.总结文档/go/ch1/4_delve/defer.go:10 (hits goroutine(1):1 total:1) (PC: 0x4cdaff)
     5: )
     6:
     7: var first = "panic in defer"
     8: var second = "panic in main"
     9:
=>  10: func main() {
    11:          defer func() {
    12:                  for {
    13:                          if err := recover(); err != nil {
    14:                                  log.Println(err)
    15:                          }else{
received SIGINT, stopping process (will not forward signal)

单步执行进入 main 函数内部,断点走到第 11 行 next(简:n)

     6:
     7: var first = "panic in defer"
     8: var second = "panic in main"
     9:
    10: func main() {
=>  11:          defer func() {
    12:                  for {
    13:                          if err := recover(); err != nil {
    14:                                  log.Println(err)
    15:                          }else{
    16:                                  log.Fatalln("fatal")

argslocals 命令查看函数的参数和局部变量:

args
(no args)
locals
(no locals)

该程序没有局部变量,所以没有相关参数信息

stack 查看当前执行函数的栈帧信息:

stack
0  0x00000000004cdb16 in main.main
   at C:/Users/y30002195/Desktop/已完成/0.总结文档/go/ch1/4_delve/defer.go:11
1  0x000000000043a40a in runtime.main
   at c:/go/src/runtime/proc.go:203
2  0x0000000000464b21 in runtime.goexit
   at c:/go/src/runtime/asm_amd64.s:1373

goroutine/goroutines 查看当前 goroutine 信息:

goroutine
Thread 14264 at C:/Users/y30002195/Desktop/已完成/0.总结文档/go/ch1/4_delve/defer.go:11
Goroutine 1:
        Runtime: C:/Users/y30002195/Desktop/已完成/0.总结文档/go/ch1/4_delve/defer.go:11 main.main (0x4cdb16)
        User: C:/Users/y30002195/Desktop/已完成/0.总结文档/go/ch1/4_delve/defer.go:11 main.main (0x4cdb16)
        Go: c:/go/src/runtime/asm_amd64.s:220 runtime.rt0_go (0x46289c)
        Start: c:/go/src/runtime/proc.go:113 runtime.main (0x43a250)

quit/exit 退出调试器:

q

y30002195@DESKTOP-GT8J20C MINGW64 ~/Desktop/已完成/0.总结文档/go/ch1/4_delve


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM