Delve是个啥
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.
- Go语言的调试器
- 目标:提供简单、功能齐全的Go调试工具
- 容易调用、使用
- 谁家好的代码天天需要调试呀,尽量少用
如何安装
安装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个用的多一点儿:
- attach
- debug
- exec
- core
- help
其他的看看帮助命令就好
使用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)
}
下面对调试命令进行梳理
1. attach
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
其他命令自行探索
2. debug
dlv debug ./main.go
命令参考 attach
3. exec
dlv exec ./main
命令参考 attach
Reference
https://github.com/go-delve/delve