- 开发工具
【免费下载链接】delve
Delve is a debugger for the Go programming language.
Delve 是 Go 编程语言的调试器,其命令行入口统一由dlv根命令承载。本文以仓库中自动生成的根命令使用文档 Documentation/usage/dlv.md 为主体,结合 cmd/dlv/cmds/commands.go 的命令树实现与 Documentation/usage/README.md 的使用场景说明,系统讲解dlv根命令的语法、全局选项、--参数透传机制,以及attach、connect、core、dap、debug、exec、replay、test、trace、version、log、backend等全部子命令的用法,让读者能够按需选择正确的启动方式并理解底层实现。
dlv 是什么
Delve 是一个面向 Go 程序的源码级调试器(source level debugger)。与基于 GDB 等通用调试器的方案不同,Delve 深度理解 Go 的运行时、goroutine、channel 与内联函数等特性,其官方文档将其目标定义为:为调试 Go 程序提供一个简单而强大的接口("a simple yet powerful interface for debugging Go programs")。
dlv命令允许你与程序进行交互,具体能力包括:
- 控制进程执行:运行、暂停、单步、继续,甚至(在录制回放下)反向执行;
- 求值变量:读取与修改程序变量、表达式;
- 获取线程 / goroutine 状态:列出、切换 goroutine 与线程;
- 查看 CPU 寄存器状态:打印寄存器内容;
- 以及查看调用栈、源码、类型、包、函数、动态库等丰富信息。
从源码结构看,dlv可执行文件的入口位于 cmd/dlv/main.go:它启动遥测(telemetry.Start),在CGO_CFLAGS环境变量未设置时将其默认设为-O0 -g(关闭优化并保留调试信息,这正是 Delve 能可靠调试 cgo 代码的前提),随后调用cmds.New(false).Execute()进入由 Cobra 框架构建的完整命令树 cmd/dlv/cmds/commands.go。
根命令语法与 Synopsis
dlv根命令的使用文档(Documentation/usage/dlv.md)给出的核心描述如下:
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.
在源码中,这段描述被定义为根命令的Long说明(cmd/dlv/cmds/commands.go),而Short描述为 "Delve is a debugger for the Go programming language."。
通过--向目标程序传递参数
dlv根命令支持一种关键的参数透传机制:使用--分隔符把后续所有参数原样传递给被调试的程序。官方文档给出的示例为:
dlv exec ./hello -- server --config conf/config.toml这条命令等价于:先用dlv exec启动并调试预编译好的./hello二进制,然后向hello进程本身传递server --config conf/config.toml这组启动参数。这在调试带命令行参数的服务器程序(如配置文件路径、监听端口等)时非常常用。同样的模式也适用于其他子命令,例如dlv test中可用--传递-test.run等 go test 标志:
dlv test [package] -- -test.run TestSomething -test.v -other-argument根命令选项
dlv根命令自身只暴露一个帮助选项:
-h, --help help for dlv而真正承载调试能力的是庞大的全局(持久化)标志与各子命令标志,详见下文。
全局(持久化)选项:影响所有子命令
在 cmd/dlv/cmds/commands.go 中,这些选项通过rootCommand.PersistentFlags()注册,因此对debug、exec、attach、test、trace等几乎所有子命令都生效。下表完整罗列了这些全局选项及其默认值与作用:
| 选项 | 默认值 | 说明 |
|---|---|---|
-l, --listen string | 127.0.0.1:0 | 调试服务器监听地址;以unix:前缀可改用 Unix domain socket |
--log | false | 启用调试服务器日志 |
--log-output string | 空 | 逗号分隔的日志组件列表(见dlv help log),可选值包括debugger、gdbwire、lldbout、debuglineerr、rpc、dap、fncall、minidump、stack |
--log-dest string | 空 | 将日志写入指定文件或文件描述符 |
--headless | false | 仅运行调试服务器(无终端),同时接受 JSON-RPC 或 DAP 客户端连接 |
--accept-multiclient | false | 允许 headless 服务器接受多个客户端连接(JSON-RPC 或 DAP) |
--api-version int | 2 | headless 模式下选用的 JSON-RPC API 版本,唯一有效值是 2;可通过RPCServer.SetApiVersion重置,详见 Documentation/api/json-rpc/README.md |
--init string | 空 | 终端客户端启动时执行的初始化文件 |
--build-flags string | 平台相关 | 传给编译器的构建标志,例如--build-flags="-tags=integration -mod=vendor -cover -v";Windows 上对旧版 Go 会自动附加-ldflags='-linkmode internal'以规避 golang/go#13154 |
--wd string | 空 | 目标程序的工作目录 |
--check-go-version | true | 当本机 Go 版本与 Delve 不兼容(过旧或过新)时直接退出 |
--only-same-user | true | 仅允许与启动该 Delve 实例的用户相同的连接接入(headless 安全选项) |
--backend string | default | 后端选择,可选default、native、lldb、rr(详见dlv help backend) |
-r, --redirect stringArray | [] | 目标进程的重定向规则(见dlv help redirect) |
--allow-non-terminal-interactive | false | 允许 stdin/stdout/stderr 不是终端的交互式会话 |
--disable-aslr | false | 禁用地址空间随机化(ASLR) |
需要说明的是,--headless与终端模式的组合构成了 Delve 两种典型使用形态(见 Documentation/usage/README.md):
- 不指定
--headless:Delve 自动启动默认的终端客户端,进入交互式调试界面; - 指定
--headless:只启动后端服务器,进入调试会话后等待客户端通过 JSON-RPC 或 DAP 连接,可与dlv connect、VS Code Go、GoLand 等前端配合实现远程调试。
子命令全景(SEE ALSO 详解)
dlv根命令文档的 SEE ALSO 部分列出了全部子命令,其实际注册代码位于 cmd/dlv/cmds/commands.go。按使用场景可划分为以下五类。
1. 指定目标并启动调试(默认终端界面)
这一类子命令都会在启动后进入默认的终端交互界面:
dlv debug [package]— 编译并以禁用优化的方式启动调试(文档)
默认编译当前目录下的main包并开始调试,也可指定其他包名。Delve 会以关闭优化(-gcflags="all=-N -l")的方式编译目标,以保证变量求值与单步调试的准确性。特有选项:
--continue 调试进程启动后立即继续运行 --output string 编译产物的输出路径 --rr-cleanup 分离时删除包含调试录制的目录(默认 true) --tty string 目标程序使用的 TTYdlv test [package]— 编译测试二进制并开始调试(文档)
以禁用优化的方式编译测试二进制并进入调试会话。默认调试当前目录的测试,也可指定包。用--分隔符向测试程序传递参数(如-test.run、-test.v)。特有选项:--output string。
dlv exec <path/to/binary>— 执行预编译二进制并开始调试(文档)
Delve 会 exec 该二进制并立即附加开始调试。注意:若二进制编译时未禁用优化,调试体验会大打折扣。官方建议在 Go 1.10 及以后使用-gcflags="all=-N -l"编译调试用二进制,更早版本使用-gcflags="-N -l"。特有选项与debug相同(--continue、--tty、--rr-cleanup)。
dlv attach pid [executable]— 附加到正在运行的进程(文档)
Delve 接管一个已运行进程并开启新调试会话;退出时会询问是让进程继续运行还是将其杀死。在源码中该子命令要求必须提供 PID,否则报错 "you must provide a PID"(commands.go)。特有选项:
--continue 附加后继续运行被调试进程 --waitfor string 等待名称以该前缀开头的进程出现 --waitfor-interval float 进程列表轮询间隔(毫秒,默认 1) --waitfor-duration float 等待进程的总时长dlv core <executable> <core>— 检查核心转储文件(文档)
打开指定的 core 文件与对应可执行文件,检查转储时进程的状态。当前支持 linux/amd64、linux/arm64 的 core 文件、windows/amd64 的 minidump,以及 Delvedump命令生成的 core 文件。源码中还隐藏了一个-c标志以便与coredumpctl兼容(commands.go)。
dlv replay [trace directory]— 回放 rr 录制轨迹(文档)
打开 mozilla rr 生成的录制轨迹进行回放调试。该子命令仅在检测到系统安装了rr(exec.LookPath("rr"))时才会注册(commands.go),并自动将后端切换为rr、禁用rr-cleanup。
2. 追踪目标程序执行
dlv trace [package] regexp— 编译并开始追踪程序(文档)
在所有匹配正则表达式的函数上设置 tracepoint(追踪点),命中时输出信息,适合只想了解进程执行了哪些函数、而不想进入完整调试会话的场景。追踪输出打印到 stderr,因此可通过重定向 stdout 来只保留追踪结果。特有选项:
--ebpf 使用 eBPF 追踪(实验性) -e, --exec string 要执行并追踪的二进制文件 --follow-calls int 递归追踪子函数到指定深度,支持 defer 函数与动态返回/传参的函数 --output string 编译产物输出路径 -p, --pid int 要附加的 PID -s, --stack int 显示指定深度的堆栈(--ebpf 模式下忽略) -t, --test 追踪测试二进制 --timestamp 输出中显示时间戳 -v, --verbose int 参数详细度:0=值, 1=类型, 2=内联, 3=展开, 4=完整(默认 0)3. 启动 headless 后端与远程客户端
dlv --headless <command> <target> <args>— headless 调试服务器(见 Documentation/api/ClientHowto.md#spawning-the-backend)
只启动服务器、进入指定目标的调试会话并等待客户端通过 JSON-RPC 或 DAP 接入。<command>可为debug、test、exec、attach、core或replay中的任意一个。若不指定--headless,则会自动启动默认终端客户端。可与 dlv connect、VS Code Go、GoLand 等配合实现远程调试。
dlv dap— 纯 DAP 服务器(文档)
启动一个始终 headless、仅通过 Debug Adaptor Protocol(DAP)通信的 TCP 服务器,要求 DAP 客户端(如 VS Code)连接并通过 launch/attach 配置指定目标。客户端 launch 配置可指定的模式包括:
launch + exec(执行预编译二进制,同dlv exec)launch + debug(编译并启动,同dlv debug)launch + test(编译并测试,同dlv test)launch + replay(回放 rr 轨迹,同dlv replay)launch + core(回放 core 文件,同dlv core)attach + local(附加运行中的进程,同dlv attach)
注意事项:程序路径与输出二进制路径相对 dlv 的工作目录解释;该服务器不接受多客户端连接(--accept-multiclient),如需多客户端应改用dlv [command] --headless配合 DAP 的 attach + remote 配置;不支持--continue,可通过 launch/attach 的stopOnEntry属性控制会话开始时是否恢复执行。特殊标志--client-addr让服务器主动拨号到等待中的 DAP 客户端(支持unix:前缀),会话结束后服务器进程退出。
dlv connect <addr>— 用终端客户端连接 headless 服务器(文档)
启动一个终端界面客户端并通过 JSON-RPC 连接到正在运行的 headless 服务器;地址同样支持unix:前缀。注意:dlv connect只与--headless模式兼容,不兼容dlv dap启动的服务器。
4. 帮助类子命令
dlv help [command]:根命令帮助入口,可查看任意子命令的详细用法;dlv log:关于日志标志的帮助(文档);dlv backend:关于--backend标志的帮助(文档);dlv redirect:关于--redirect重定向规则的帮助(文档);dlv version:打印版本信息(文档),可用-v输出详细构建信息(version.BuildInfo())。
另外,仓库中还存在一个已废弃的run子命令,其输出提示 "This command is deprecated, please use 'debug' instead.",在命令树中标记为隐藏(commands.go),新代码应统一使用debug。
环境变量
Delve 还会读取以下环境变量(见 Documentation/usage/README.md):
| 环境变量 | 作用 |
|---|---|
$DELVE_EDITOR | 供edit命令使用;未设置时回退到$EDITOR |
$DELVE_PAGER | 供输出量较大的命令使用;未设置时回退到$PAGER,两者均未设置则使用more |
$TERM | 决定是否使用 ANSI 转义码进行彩色输出 |
$DELVE_DEBUGSERVER_PATH | 在 macOS 上定位 debugserver 可执行文件 |
此外,入口程序 cmd/dlv/main.go 还会在CGO_CFLAGS未设置时将其预设为-O0 -g,以保证 cgo 代码的可调试性。
配置与命令历史文件位置
终端客户端的行为由配置文件config.yml控制,命令历史存储在.dbg_history中。文件位置遵循 XDG 规范(Documentation/cli/README.md):
- 若设置了
$XDG_CONFIG_HOME,则位于$XDG_CONFIG_HOME/dlv; - 否则在 Linux 上位于
$HOME/.config/dlv,在其他系统上位于$HOME/.dlv。
所有可配置项及其默认值见 Documentation/cli/config.md。
终端客户端命令速查
启动调试会话后进入的终端界面提供了一组功能强大的交互命令,按功能分类速查如下(完整语法参见 Documentation/cli/README.md):
| 类别 | 命令 |
|---|---|
| 运行控制 | continue(c)、next(n)、step(s)、stepout(so)、step-instruction、next-instruction、restart、rewind(rw)、rev、rebuild |
| 断点管理 | break(b)、breakpoints(bp)、clear、clearall、condition(cond)、on、toggle、trace(t)、watch |
| 变量与内存 | print(p)、set、locals、args、vars、examinemem(x)、display、regs、whatis |
| 线程与 goroutine | goroutine(gr)、goroutines(grs)、thread(tr)、threads |
| 调用栈与帧 | stack(bt)、frame、up、down、deferred |
| 其他 | list(ls/l)、disassemble、dump、source、config、edit、funcs、types、packages、sources、libraries、checkpoint、transcript、target、exit(quit/q) |
其中若干命令与本文主题直接相关:condition支持-hitcount、-per-g-hitcount与-clear三种形态,表达式语法见 Documentation/cli/expr.md,条件求值机制见 Documentation/cli/cond.md;break的位置定位符(locspec)支持<address>、<filename>:<line>、<line>、+<offset>、-<offset>、<function>[:<line>]、/<regex>/七种形式,详见 Documentation/cli/locspec.md;source命令可执行命令文件,.star结尾的文件会作为 Starlark 脚本解释(Documentation/cli/starlark.md),仓库_fixtures/目录下(如amend_breakpoint.star、linked_list.star)即有大量可直接参考的示例脚本。
总结:如何选择正确的 dlv 启动方式
| 场景 | 推荐命令 |
|---|---|
| 调试当前目录的 Go 程序 | dlv debug |
| 调试预编译的二进制 | dlv exec ./binary |
| 附加到运行中的进程 | dlv attach <pid> |
| 调试单元测试 | dlv test [package] |
| 追踪函数调用 | dlv trace [package] <regexp> |
| 检查崩溃转储 | dlv core <exe> <core> |
| 回放录制轨迹 | dlv replay <trace>(需安装 rr) |
| 远程/编辑器集成(JSON-RPC) | dlv --headless debug+dlv connect或编辑器前端 |
| 编辑器集成(DAP,如 VS Code) | dlv dap |
最后提醒:完整的命令用法以仓库中自动生成的 dlv.md 及各子命令文档(Documentation/usage/ 目录)为准,终端内随时可用dlv help [command]查看。
- 开发工具
【免费下载链接】delve
Delve is a debugger for the Go programming language.
相关推荐
git-sim命令行参数完全手册:全局选项与子命令详解
git sim命令行参数完全手册:全局选项与子命令详解 git sim是一个强大的Git可视化模拟工具,通过单个终端命令就能在您自己的仓库中 视觉化模拟Git操
开发工具Velero(Ark)CLI 参考:ark 根命令、全局选项与子命令体系完全指南
Velero(Ark)CLI 参考:ark 根命令、全局选项与子命令体系完全指南 本文以仓库 site/content/docs/v0.4.0/cli refe
云原生灾备存储后端Linera CLI 命令完全参考:`linera` 命令行工具的全局选项、全部子命令与源码级解析
Linera CLI 命令完全参考: linera 命令行工具的全局选项、全部子命令与源码级解析 linera 是 Linera 协议的官方客户端实现与命令行工
区块链Web3
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考