Go调试工具—— Delve

参考: Go调试工具------ Delve - 慢行厚积 - 博客园

  1. 查看版本,帮助信息
bash 复制代码
[root@etcd2 encryption]# dlv version

Delve Debugger

Version: 1.3.2

Build: $Id: 569ccbd514fc47c8b4c521b142556867ec5e6917 $

[root@etcd2 encryption]# 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.

      --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.



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

[root@etcd2 encryption]# 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")



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')

      --wd string            Working directory for running the program. (default ".")
  1. 调试
bash 复制代码
[root@etcd2 dlvtest]# dlv debug test.go

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.

(dlv) c

Starting main

count :  0

count :  1

count :  2

count :  3

count :  4

count :  5

count :  6

count :  7

count :  8

count :  9

Process 33806 has exited with status 0

(dlv) r

Process restarted with PID 34040

(dlv) b main.main

Breakpoint 1 set at 0x4aa708 for main.main() ./test.go:16

(dlv) b main.counting

Breakpoint 2 set at 0x4aa65f for main.counting() ./test.go:8

(dlv) c

> main.main() ./test.go:16 (hits goroutine(1):1 total:1) (PC: 0x4aa708)

    11:         c <- i

    12:     }

    13:     close(c)

    14: }

    15:

=>  16: func main() {

    17:     msg := "Starting main"

    18:     fmt.Println(msg)

    19:     bus := make(chan int)

    20:     msg = "starting a gofunc"

    21:     go counting(bus)

(dlv) bp

Breakpoint runtime-fatal-throw at 0x42e020 for runtime.fatalthrow() /usr/local/go/src/runtime/panic.go:820 (0)

Breakpoint unrecovered-panic at 0x42e090 for runtime.fatalpanic() /usr/local/go/src/runtime/panic.go:847 (0)

        print runtime.curg._panic.arg

Breakpoint 1 at 0x4aa708 for main.main() ./test.go:16 (1)

Breakpoint 2 at 0x4aa65f for main.counting() ./test.go:8 (0)

(dlv) list

> main.main() ./test.go:16 (hits goroutine(1):1 total:1) (PC: 0x4aa708)

    11:         c <- i

    12:     }

    13:     close(c)

    14: }

    15:

=>  16: func main() {

    17:     msg := "Starting main"

    18:     fmt.Println(msg)

    19:     bus := make(chan int)

    20:     msg = "starting a gofunc"

    21:     go counting(bus)

(dlv) n

> main.main() ./test.go:17 (PC: 0x4aa71f)

    12:     }

    13:     close(c)

    14: }

    15:

    16: func main() {

=>  17:     msg := "Starting main"

    18:     fmt.Println(msg)

    19:     bus := make(chan int)

    20:     msg = "starting a gofunc"

    21:     go counting(bus)

    22:     for count := range bus{

(dlv) p msg

"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00...+4439097 more"

(dlv) locals bus

(no locals)

(dlv) locals msg

msg = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00...+4439097 more"

(dlv) s

> main.main() ./test.go:18 (PC: 0x4aa737)

    13:     close(c)

    14: }

    15:

    16: func main() {

    17:     msg := "Starting main"

=>  18:     fmt.Println(msg)

    19:     bus := make(chan int)

    20:     msg = "starting a gofunc"

    21:     go counting(bus)

    22:     for count := range bus{

    23:         fmt.Println("count : ", count)

(dlv) locals

msg = "Starting main"

(dlv) p count

Command failed: could not find symbol value for count

(dlv) s

> fmt.Println() /usr/local/go/src/fmt/print.go:273 (PC: 0x4a4733)

   268: }

   269:

   270: // Println formats using the default formats for its operands and writes to standard output.

   271: // Spaces are always added between operands and a newline is appended.

   272: // It returns the number of bytes written and any write error encountered.

=> 273: func Println(a ...interface{}) (n int, err error) {

   274:         return Fprintln(os.Stdout, a...)

   275: }

   276:

   277: // Sprintln formats using the default formats for its operands and returns the resulting string.

   278: // Spaces are always added between operands and a newline is appended.

(dlv) s

> fmt.Println() /usr/local/go/src/fmt/print.go:274 (PC: 0x4a4758)

   269:

   270: // Println formats using the default formats for its operands and writes to standard output.

   271: // Spaces are always added between operands and a newline is appended.

   272: // It returns the number of bytes written and any write error encountered.

   273: func Println(a ...interface{}) (n int, err error) {

=> 274:         return Fprintln(os.Stdout, a...)

   275: }

   276:

   277: // Sprintln formats using the default formats for its operands and returns the resulting string.

   278: // Spaces are always added between operands and a newline is appended.

   279: func Sprintln(a ...interface{}) string {

(dlv) n

Starting main

> main.main() ./test.go:19 (PC: 0x4aa7c8)

Values returned:

        n: 14

        err: error nil



    14: }

    15:

    16: func main() {

    17:     msg := "Starting main"

    18:     fmt.Println(msg)

=>  19:     bus := make(chan int)

    20:     msg = "starting a gofunc"

    21:     go counting(bus)

    22:     for count := range bus{

    23:         fmt.Println("count : ", count)

    24:     }

(dlv) n

> main.main() ./test.go:20 (PC: 0x4aa7eb)

    15:

    16: func main() {

    17:     msg := "Starting main"

    18:     fmt.Println(msg)

    19:     bus := make(chan int)

=>  20:     msg = "starting a gofunc"

    21:     go counting(bus)

    22:     for count := range bus{

    23:         fmt.Println("count : ", count)

    24:     }

    25: }

(dlv) n

> main.main() ./test.go:21 (PC: 0x4aa803)

    16: func main() {

    17:     msg := "Starting main"

    18:     fmt.Println(msg)

    19:     bus := make(chan int)

    20:     msg = "starting a gofunc"

=>  21:     go counting(bus)

    22:     for count := range bus{

    23:         fmt.Println("count : ", count)

    24:     }

    25: }

(dlv) p msg == "Starting main"

false

(dlv) p msg == "Starting a gofunc"

false

(dlv) p msg == "starting a gofunc"

true

(dlv) whatis msg

string

(dlv) c

> main.counting() ./test.go:8 (hits goroutine(6):1 total:1) (PC: 0x4aa65f)

     3: import (

     4:     "fmt"

     5:     "time"

     6: )

     7:

=>   8: func counting(c chan<- int){

     9:     for i := 0; i < 10; i++{

    10:         time.Sleep(2 * time.Second)

    11:         c <- i

    12:     }

    13:     close(c)

(dlv) help goroutine

Shows or changes current goroutine



        goroutine

        goroutine <id>

        goroutine <id> <command>



Called without arguments it will show information about the current goroutine.

Called with a single argument it will switch to the specified goroutine.

Called with more arguments it will execute a command on the specified goroutine.

(dlv) goroutine

Thread 34040 at ./test.go:8

Goroutine 6:

        Runtime: ./test.go:8 main.counting (0x4aa65f)

        User: ./test.go:8 main.counting (0x4aa65f)

        Go: ./test.go:21 main.main (0x4aa825)

        Start: ./test.go:8 main.counting (0x4aa650)

(dlv) groutine 1

Command failed: command not available

(dlv) goroutine 1

Switched from 6 to 1 (thread 34040)

(dlv) goroutine

Thread 34040 at ./test.go:8

Goroutine 1:

        Runtime: /usr/local/go/src/runtime/chan.go:421 runtime.chanrecv (0x405b34)

        User: ./test.go:22 main.main (0x4aa849)

        Go: /usr/local/go/src/runtime/asm_amd64.s:220 runtime.rt0_go (0x458e34)

        Start: /usr/local/go/src/runtime/proc.go:113 runtime.main (0x42f790)

(dlv) locals

(no locals)

(dlv) goroutine 6

Switched from 1 to 6 (thread 34040)

(dlv) help goroutines

List program goroutines.



        goroutines [-u (default: user location)|-r (runtime location)|-g (go statement location)|-s (start location)] [ -t (stack trace)]



Print out info for every goroutine. The flag controls what information is shown along with each goroutine:



        -u      displays location of topmost stackframe in user code

        -r      displays location of topmost stackframe (including frames inside private runtime functions)

        -g      displays location of go instruction that created the goroutine

        -s      displays location of the start function

        -t      displays stack trace of goroutine



If no flag is specified the default is -u.

(dlv) goroutines

  Goroutine 1 - User: ./test.go:22 main.main (0x4aa849)

  Goroutine 2 - User: /usr/local/go/src/runtime/proc.go:305 runtime.gopark (0x42fd0b)

  Goroutine 3 - User: /usr/local/go/src/runtime/proc.go:305 runtime.gopark (0x42fd0b)

  Goroutine 4 - User: /usr/local/go/src/runtime/proc.go:305 runtime.gopark (0x42fd0b)

  Goroutine 5 - User: /usr/local/go/src/runtime/proc.go:305 runtime.gopark (0x42fd0b)

* Goroutine 6 - User: ./test.go:8 main.counting (0x4aa65f) (thread 34040)

[6 goroutines]

(dlv) args

c = chan<- int 0/0

(dlv) c

count :  0

count :  1

count :  2

count :  3

count :  4

count :  5

count :  6

count :  7

count :  8

count :  9

Process 34040 has exited with status 0

(dlv) r

Process restarted with PID 35004

(dlv) b main.main

Command failed: Breakpoint exists at /home/gowork/src/github.com/user/dlvtest/test.go:16 at 4aa708

(dlv) c

Starting main

> main.counting() ./test.go:8 (hits goroutine(6):1 total:1) (PC: 0x4aa65f)

     3: import (

     4:     "fmt"

     5:     "time"

     6: )

     7:

=>   8: func counting(c chan<- int){

     9:     for i := 0; i < 10; i++{

    10:         time.Sleep(2 * time.Second)

    11:         c <- i

    12:     }

    13:     close(c)

(dlv) stepout

count :  0

count :  1

count :  2

count :  3

count :  4

count :  5

count :  6

count :  7

count :  8

> runtime.goexit() /usr/local/go/src/runtime/asm_amd64.s:1358 (PC: 0x45ae81)

Warning: debugging optimized function

Values returned:



  1353:

  1354: // The top-most function running on a goroutine

  1355: // returns to goexit+PCQuantum.

  1356: TEXT runtime·goexit(SB),NOSPLIT,$0-0

  1357:         BYTE    $0x90   // NOP

=>1358:         CALL    runtime·goexit1(SB)     // does not return

  1359:         // traceback from goexit1 must hit code range of goexit

  1360:         BYTE    $0x90   // NOP

  1361:

  1362: // This is called from .init_array and follows the platform, not Go, ABI.

  1363: TEXT runtime·addmoduledata(SB),NOSPLIT,$0-0

(dlv) r

Process restarted with PID 35179

(dlv) breakpoints

Breakpoint runtime-fatal-throw at 0x42e020 for runtime.fatalthrow() /usr/local/go/src/runtime/panic.go:820 (0)

Breakpoint unrecovered-panic at 0x42e090 for runtime.fatalpanic() /usr/local/go/src/runtime/panic.go:847 (0)

        print runtime.curg._panic.arg

Breakpoint 1 at 0x4aa65f for main.counting() ./test.go:8 (0)

(dlv) help on

Executes a command when a breakpoint is hit.



        on <breakpoint name or id> <command>.



Supported commands: print, stack and goroutine)

(dlv) b /home/gowork/src/github.com/user/dlvtest/test.go:21

Breakpoint 2 set at 0x4aa803 for main.main() ./test.go:21

(dlv) breakpoints

Breakpoint runtime-fatal-throw at 0x42e020 for runtime.fatalthrow() /usr/local/go/src/runtime/panic.go:820 (0)

Breakpoint unrecovered-panic at 0x42e090 for runtime.fatalpanic() /usr/local/go/src/runtime/panic.go:847 (0)

        print runtime.curg._panic.arg

Breakpoint 1 at 0x4aa65f for main.counting() ./test.go:8 (0)

Breakpoint 2 at 0x4aa803 for main.main() ./test.go:21 (0)

(dlv) c

Starting main

> main.main() ./test.go:21 (hits goroutine(1):1 total:1) (PC: 0x4aa803)

    16: func main() {

    17:     msg := "Starting main"

    18:     fmt.Println(msg)

    19:     bus := make(chan int)

    20:     msg = "starting a gofunc"

=>  21:     go counting(bus)

    22:     for count := range bus{

    23:         fmt.Println("count : ", count)

    24:     }

    25: }

(dlv) help set

Changes the value of a variable.



        [goroutine <n>] [frame <m>] set <variable> = <value>



See $GOPATH/src/github.com/go-delve/delve/Documentation/cli/expr.md for a description of supported expressions. Only numerical variables and pointers can be changed.

(dlv) set msg = "change msg"

Command failed: literal string can not be allocated because function calls are not allowed without using 'call'

(dlv) up

> main.main() ./test.go:21 (hits goroutine(1):1 total:1) (PC: 0x4aa803)

Frame 1: /usr/local/go/src/runtime/proc.go:203 (PC: 42f964)

   198:                 // A program compiled with -buildmode=c-archive or c-shared

   199:                 // has a main, but it is not executed.

   200:                 return

   201:         }

   202:         fn := main_main // make an indirect call, as the linker doesn't know the address of the main package when laying down the runtime

=> 203:         fn()

   204:         if raceenabled {

   205:                 racefini()

   206:         }

   207:

   208:         // Make racy client program work: if panicking on

(dlv) down

> main.main() ./test.go:21 (hits goroutine(1):1 total:1) (PC: 0x4aa803)

Frame 0: ./test.go:21 (PC: 4aa803)

    16: func main() {

    17:     msg := "Starting main"

    18:     fmt.Println(msg)

    19:     bus := make(chan int)

    20:     msg = "starting a gofunc"

=>  21:     go counting(bus)

    22:     for count := range bus{

    23:         fmt.Println("count : ", count)

    24:     }

    25: }

(dlv) exit

[root@etcd2 dlvtest]# go run test.go

Starting main

count :  0

count :  1

count :  2

count :  3

count :  4

count :  5

count :  6

count :  7

count :  8

count :  9


attach 测试:

root      59253  3.6  1.0 308592 10032 pts/1    Sl+  14:21   0:00 go run test.go

root      59276  0.0  0.0 102724   956 pts/1    Sl+  14:21   0:00 /tmp/go-build582338132/b001/exe/test

root      59282  0.0  0.0 112708   972 pts/0    S+   14:21   0:00 grep --color=auto test

[root@etcd2 dlvtest]# dlv attach 59253

Type 'help' for list of commands.

(dlv) c

Process 59253 has exited with status 0

(dlv)
  1. 测试代码
Go 复制代码
package main



import (

    "fmt"

    "time"

)



func counting(c chan<- int){

    for i := 0; i < 10; i++{

        time.Sleep(2 * time.Second)

        c <- i

    }

    close(c)

}



func main() {

    msg := "Starting main"

    fmt.Println(msg)

    bus := make(chan int)

    msg = "starting a gofunc"

    go counting(bus)

    for count := range bus{

        fmt.Println("count : ", count)

    }

}
相关推荐
学不会•2 小时前
css数据不固定情况下,循环加不同背景颜色
前端·javascript·html
活宝小娜4 小时前
vue不刷新浏览器更新页面的方法
前端·javascript·vue.js
程序视点4 小时前
【Vue3新工具】Pinia.js:提升开发效率,更轻量、更高效的状态管理方案!
前端·javascript·vue.js·typescript·vue·ecmascript
coldriversnow4 小时前
在Vue中,vue document.onkeydown 无效
前端·javascript·vue.js
我开心就好o4 小时前
uniapp点左上角返回键, 重复来回跳转的问题 解决方案
前端·javascript·uni-app
开心工作室_kaic5 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
刚刚好ā5 小时前
js作用域超全介绍--全局作用域、局部作用、块级作用域
前端·javascript·vue.js·vue
qq_17448285756 小时前
springboot基于微信小程序的旧衣回收系统的设计与实现
spring boot·后端·微信小程序
锅包肉的九珍6 小时前
Scala的Array数组
开发语言·后端·scala
心仪悦悦6 小时前
Scala的Array(2)
开发语言·后端·scala