当前位置: 首页 > article >正文

Go调试工具—— Delve

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

1. 查看版本,帮助信息

[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 ".")

2. 调试

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

3. 测试代码

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)

    }

}


http://www.kler.cn/a/319196.html

相关文章:

  • css中的变量使用
  • BILSTM法律网站用户提问自动分类
  • 批量从Excel某一列中找到符合要求的值并提取其对应数据
  • 有了Makefile, CMake存在的意义是什么?如何借助Makefile构建ObjC语言编译环境?如何获取编译器的版本号?
  • Vim 编辑器学习笔记
  • Brave127编译指南 Windows篇:部署Node.js(五)
  • 2024 ICPC ShaanXi Provincial Contest —— C. Seats(个人理解)拓扑+dfs
  • 深度学习(4):torch.nn.Module
  • flink 的 Barrier 对齐 的优劣详解:
  • PHP 中 empty() 函数的作用
  • PAT甲级-1083 List Grades
  • 如何选择渲染集群管理软件?
  • css基础知识笔记
  • 【Pyside】pycharm2024配置conda虚拟环境
  • Jmeter 线程组解析
  • 产品经理如何转到AI赛道?优势在哪?待遇如何?
  • C++系列-STL容器中统计算法count, count_if
  • uniapp调用安卓service实现后台运行
  • 华为OD机试真题-最少交换次数-2024年OD统一考试(E卷)
  • fastadmin前端切换成英文,后台中文,修改JS文件
  • Milvus - 从数据库到 Partition Key 实现多租户
  • STM32 使用 CubeMX 实现按键外部中断
  • flink 为啥使用MemorySegment 来管理内存
  • 性能测试1初步使用Jmeter
  • el-table中根据状态改单元格样式
  • 医学数据分析实训 项目五 分类分析--乳腺癌数据分析与诊断