Delve is a debugger for the Go programming language. The goal of the project is to provide a simple, full featured debugging tool for Go. Delve should be easy to invoke and easy to use. Chances are if you’re using a debugger, things aren’t going your way. With that in mind, Delve should stay out of your way as much as possible.
安装latest,最新版
go install github.com/go-delve/delve/cmd/dlv@latest
如果它报这个错误,证明dlv不支持该平台
go install github.com/go-delve/delve/cmd/dlv@latest
D:\goworkspace\pkg\mod\github.com\go-delve\delve@v1.21.2\service\debugger\debugger.go:32:2: found packages native (dump_other.go) and your_windows_architecture_is_not_supported_by_delve (support_sentinel_windows.go) in D:\goworkspace\pkg\mod\github.com\go-delve\delve@v1.21.2\pkg\proc\native
go version
go version go1.20 linux/arm64
dlv version
Delve Debugger
Version: 1.21.2
Build: $Id: 98f8ab2662d926245917ade2f2bb38277315c7fc $
不会用就看看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 with a terminal client.
core Examine a core dump.
dap Starts a headless 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
test Compile test binary and begin debugging program.
trace Compile and begin tracing program.
version Prints version.
Additional help topics:
dlv backend Help about the --backend flag.
dlv log Help about logging flags.
dlv redirect Help about file redirection.
Use "dlv [command] --help" for more information about a command.
命令名 | 作用 |
---|---|
attach | Attach to running process and begin debugging (白话:跟某个进程建立联系,跟某个进程搞搞暧昧呗) |
connect | Connect to a headless debug server with a terminal client.(白话:作为一个客户端,连接到一个(无头?不可描述的)调试服务) |
core | Examine a core dump. (白话:检查核心转储) |
dap | Starts a headless TCP server communicating via Debug Adaptor Protocol (DAP). (白话:启一个服务,让客户端连接调试) |
debug | Compile and begin debugging main package in current directory, or the package specified. (白话:编译并开始调试在当前目录的main包,或者其他给定的包) |
exec | Execute a precompiled binary, and begin a debug session. (白话:执行一个预编译好的二进制文件,并开启一个调试会话) |
help | Help about any command (它会帮你哦,别的可以不会,这个必须会) |
test | Compile test binary and begin debugging program. (编译测试二进制、并开始调试程序) |
trace | Compile and begin tracing program. (追踪模式) |
version | Prints version. (版本信息啦) |
总结一下,上述命令中,如下5个用的多一点儿:
其他的看看帮助命令就好
使用dlv help 子命令
可查看子命令的帮助文档哈
另外还有如下不常用的命令,暂不做介绍
Additional help topics:
dlv backend Help about the --backend flag.
dlv log Help about logging flags.
dlv redirect Help about file redirection.
搞一个先决条件,创建一个main.go文件,写一段简单的代码进去。
就以如下代码为例,main函数中写了一个简易版的httpServer,80端口开放,访问 “http://localhost:80/” 路径,则执行一次斐波那契数列的函数。
package main
import "net/http"
func main() {
http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
fib(3)
})
if err := http.ListenAndServe(":80", nil); err != nil {
panic(err)
}
}
func fib(n int) int {
if n < 2 {
return 1
}
return fib(n-1) + fib(n-2)
}
下面对调试命令进行梳理
dlv help attach
Attach to an already running process and begin debugging it.
This command will cause Delve to take control of an already running process, and
begin a new debug session. When exiting the debug session you will have the
option to let the process continue or kill it.
Usage:
dlv attach pid [executable] [flags]
Flags:
--continue Continue the debugged process on start.
-h, --help help for attach
--waitfor string Wait for a process with a name beginning with this prefix
--waitfor-duration float Total time to wait for a process
--waitfor-interval float Interval between checks of the process list, in millisecond (default 1)
Global Flags:
--accept-multiclient Allows a headless server to accept multiple client connections via JSON-RPC or DAP.
--allow-non-terminal-interactive Allows interactive sessions of Delve that don't have a terminal as stdin, stdout and stderr
--api-version int Selects JSON-RPC API version when headless. New clients should use v2. Can be reset via RPCServer.SetApiVersion. See Documentation/api/json-rpc/README.md. (default 1)
--backend string Backend selection (see 'dlv help backend'). (default "default")
--check-go-version Exits if the version of Go in use is not compatible (too old or too new) with the version of Delve. (default true)
--headless Run debug server only, in headless mode. Server will accept both JSON-RPC or DAP client connections.
--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)
该命令主要部分: dlv attach pid,该pid是一个Go程序的pid
go build ./main.go
生成了 main
可执行文件
使用nohub ./main
或者 setsid ./main
启动 main 文件,此时该文件加载进内存后对应一个进程ID。
这里使用ps -ef | grep main
找到程序的pid
使用dlv attach PID 进行调试
输入help 看一下帮助命令
root@Ophelia:~/test# dlv attach 1680
Type 'help' for list of commands.
(dlv) help
The following commands are available:
Running the program:
call ------------------------ Resumes process, injecting a function call (EXPERIMENTAL!!!)
continue (alias: c) --------- Run until breakpoint or program termination.
next (alias: n) ------------- Step over to next source line.
rebuild --------------------- Rebuild the target executable and restarts it. It does not work if the executable was not built by delve.
restart (alias: r) ---------- Restart process.
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.
Manipulating breakpoints:
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.
on --------------------- Executes a command when a breakpoint is hit.
toggle ----------------- Toggles on or off a breakpoint.
trace (alias: t) ------- Set tracepoint.
watch ------------------ Set watchpoint.
Viewing program variables and memory:
args ----------------- Print function arguments.
display -------------- Print value of an expression every time the program stops.
examinemem (alias: x) Examine raw memory at the given address.
locals --------------- Print local variables.
print (alias: p) ----- Evaluate an expression.
regs ----------------- Print contents of CPU registers.
set ------------------ Changes the value of a variable.
vars ----------------- Print package variables.
whatis --------------- Prints type of an expression.
Listing and switching between threads and goroutines:
goroutine (alias: gr) -- Shows or changes current goroutine
goroutines (alias: grs) List program goroutines.
thread (alias: tr) ----- Switch to the specified thread.
threads ---------------- Print out info for every traced thread.
Viewing the call stack and selecting frames:
deferred --------- Executes command in the context of a deferred call.
down ------------- Move the current frame down.
frame ------------ Set the current frame, or execute command on a different frame.
stack (alias: bt) Print stack trace.
up --------------- Move the current frame up.
Other commands:
config --------------------- Changes configuration parameters.
disassemble (alias: disass) Disassembler.
dump ----------------------- Creates a core dump from the current process state
edit (alias: ed) ----------- Open where you are in $DELVE_EDITOR or $EDITOR
exit (alias: quit | q) ----- Exit the debugger.
funcs ---------------------- Print list of functions.
help (alias: h) ------------ Prints the help message.
libraries ------------------ List loaded dynamic libraries
list (alias: ls | l) ------- Show source code.
packages ------------------- Print list of packages.
source --------------------- Executes a file containing a list of delve commands
sources -------------------- Print list of source files.
target --------------------- Manages child process debugging.
transcript ----------------- Appends command output to a file.
types ---------------------- Print list of types
Type help followed by a command for full documentation.
(dlv)
可以看见子命令非常之多
执行程序
序号 | 子命令 | 别名 | 描述 |
---|---|---|---|
01 | call | Resumes process, injecting a function call (EXPERIMENTAL!!!) (实验性的功能,注入一个函数调用,重新执行) | |
02 | continue | c | Run until breakpoint or program termination. (执行到断点或程序中止) |
03 | next | n | Step over to next source line. (步过下一行,下一行若是函数,则调用并返回) |
04 | rebuild | Rebuild the target executable and restarts it. It does not work if the executable was not built by delve. (重新编译目标执行文件并启动他, 若该程序不是由delve编译的,则无法执行) | |
05 | restart | r | Restart process. (重启进程) |
06 | step | s | Single step through program. (单步调试,整个程序) |
07 | step-instruction | si | Single step a single cpu instruction. (单步执行cpu指令) |
08 | stepout | os | Step out of the current function. (步出当前函数) |
操纵断点
序号 | 子命令 | 别名 | 描述 |
---|---|---|---|
01 | break | b | Sets a breakpoint. (设置一个断点) |
02 | breakpoints | bp | Print out info for active breakpoints. (打印正在使用的断点) |
03 | clear | Deletes brekpoint. (根据断点编号,删除断点) | |
04 | clearall | Deletes multiple breakpoints.(删除多个断点) | |
05 | condition | cond | Set breakpoint condition. (设置断点条件) |
06 | on | Executes a command when a breakpoint is hit. (当断点命中时候,执行一个命令) | |
07 | toggle | Toggles on or off a breakpoint. (切换断点的状态,启用或关闭) | |
08 | trace | t | Set tracepoint. (设置追踪点) |
09 | watch | Set watchpoint. (设置内存观测点,看门狗的功能) |
查看程序变量和内存
序号 | 子命令 | 别名 | 描述 |
---|---|---|---|
01 | args | Print function arguments. (打印函数参数) | |
02 | display | Print value of an expression every time the program stops. (打印表达式的值,在下一行或者下一个断点) | |
03 | examinemem | x | Examine raw memory at the given address.(检查给定地址的原始内存) |
04 | locals | Print local variables. (打印局部变量) | |
05 | p | Evaluate an expression. (计算并打印表达式结果) | |
06 | regs | Print contents of CPU registers.(打印CPU 寄存器的内容) | |
07 | set | Changes the value of a variable. (给变量设置值) | |
08 | vars | Print package variables. (打印包级别变量) | |
09 | whatis | Prints type of an expression. (打印表达式类型) |
进程、协程
序号 | 子命令 | 别名 | 描述 |
---|---|---|---|
01 | goroutine | gr | Shows or changes current goroutine. (显示或切换当前协程) |
02 | goroutines | grs | List program goroutines. (列出当前程序所有的协程) |
03 | thread | tr | Switch to the specified thread. (切换到指定的线程) |
04 | threads | Print out info for every traced thread.(打印所有线程的追踪信息) |
调用栈、栈帧
序号 | 子命令 | 别名 | 描述 |
---|---|---|---|
01 | deferred | Executes command in the context of a deferred call. (在defer调用的上下文中执行一个命令) | |
01 | down | Move the current frame down. (向下移动栈帧) | |
03 | frame | Set the current frame, or execute command on a different frame. (设置当前栈帧、或在其他栈帧执行命令) | |
04 | stack | bt | Print stack trace. (打印栈追踪信息) |
05 | up | Move the current frame up. (向上移动当前栈帧) |
其他命令
序号 | 子命令 | 别名 | 描述 |
---|---|---|---|
01 | config | Changes configuration parameters. (修改配置参数) | |
02 | disassemble | disass | Disassembler. (反汇编) |
03 | dump | Creates a core dump from the current process state. (创建核心转储) | |
04 | edit | ed | |
05 | exit | quit、q | Exit the debugger. (退出调试器) |
06 | funcs | Print list of functions.(打印所有函数) | |
07 | help | h | Prints the help message. (打印帮助信息) |
08 | libraries | List loaded dynamic libraries. (列出动态链接库) | |
09 | list | ls 、l | Show source code. (打印源码) |
10 | packages | Print list of packages.(打印包列表) | |
11 | source | Executes a file containing a list of delve commands. (执行一个包含delve命令列表的文件) | |
12 | sources | Print list of source files. (打印源码路径列表) | |
13 | target | Manages child process debugging. (管理子进程调试) | |
14 | transcript | appends command output to a file. (追加命令输出到一个文件) | |
15 | types | Print list of types.(打印类型列表) |
以上高亮的子命令用的多一些
打一套组合拳(啊打!)
设置断点的方式
break 包名.函数名
b 包名.函数名
break 文件名:行号
b 文件名行号
b main.main
b main.fib
c
n
其他终端: curl http://localhost:80
描述过于诡异
bp
,查看一下断点
clear 1
,删除一个断点,并再次查看断点
c
,此时断住不动了,怎么办,怎么办?
curl http://localhost:80
当然是在其他终端输入这个啦
此时你会发现,其他终端中卡住了
此时你需要在当前终端一直
c
c
...
c下去,直到把fib函数执行完,再次断住
此时另一个终端中有结果了哦
curl http://localhost:80
StatusCode : 200
StatusDescription : OK
Content : {}
RawContent : HTTP/1.1 200 OK
Content-Length: 0
Date: Fri, 15 Dec 2023 15:44:06 GMT
Headers : {[Content-Length, 0], [Date, Fri, 15 Dec 2023 15:44:06 GMT]}
RawContentLength : 0
其他命令自行探索
dlv debug ./main.go
命令参考 attach
dlv exec ./main
命令参考 attach
Reference
https://github.com/go-delve/delve