使用Delve调试golang程序
January 27, 2022 默认分类
Delve是Go程序的源代码级调试器.
elve通过控制进程的执行、评估变量以及提供线程/ goroutine状态、CPU寄存器状态等信息,使你能够与程序进行交互。
这个工具的目标是为调试Go程序提供一个简单而强大的接口.
使用“--”将标志传递给正在调试的程序,例如:
dlv exec ./hello -- server --config conf/config.toml
output
Usage:
dlv [command]
Available Commands:
attach 连接到正在运行的流程并开始调试.
connect 连接到无头调试服务器.
core 检查核心转储.
debug 编译并开始调试当前目录下的主包或指定的包.
exec 执行预编译的二进制文件,并开始调试会话.
help 帮助信息
run 弃用的命令。使用“debug”替代它.
test 编译测试二进制文件并开始调试程序.
trace 编译并开始跟踪程序.
version 打印版本.
Flags:
--accept-multiclient 允许无头服务器接受多个客户机连接。注意,服务器API不是可重入的,客户端必须协调.
--api-version int 无头时选择API版本. (default 1)
--backend string 后端选择:
default 在macOS上使用lldb,其他地方都是本地的.
native 本地后端.
lldb 使用lldb-server或debugserver.
rr 使用mozilla rr (https://github.com/mozilla/rr).
(default "default") 默认使用的是default
--build-flags string 生成标志,以传递给编译器.
--headless 仅在headless模式下运行调试服务器.
--init string 初始化文件,由终端客户端执行.
-l, --listen string 调试服务器监听地址. (default "localhost:0")
--log 启用调试服务器日志记录.
--log-output string 应该产生调试输出的组件的逗号分隔列表,可能的值为:
debugger 记录调试器命令
gdbwire 日志连接到gdbserial后端
lldbout 将输出从debugserver/lldb复制到标准输出
debuglineerr 读取.debug_line时日志可恢复错误
rpc 记录所有RPC消息
fncall 日志函数调用协议
minidump 日志minidump加载
使用--log启用日志时,默认为“debugger”.
--wd string 用于运行程序的工作目录. (default ".")
使用"dlv [command] --help"获取有关命令的详细信息.
dlv debug
dlv debug
编译禁用优化的程序,启动并附加到该程序。
默认情况下,没有参数,Delve将编译当前目录中的“main”包,并开始调试它。或者,您可以指定一个包名,Delve将编译该包,并开始一个新的调试会话。
Usage:
dlv debug [package] [flags]
Flags:
--output string 二进制文件的输出路径. (default "debug")
Global Flags:和上面的一样,这里省略
attach或者debug或者exec后
The following commands are available:
运行程序:
call ------------------------ 恢复进程,注入函数调用(实验!!!)。
continue (alias: c) --------- 运行直到断点或程序终止。
next (alias: n) ------------- 跳到下一个源代码行。
rebuild --------------------- 重建目标可执行文件并重新启动它。如果可执行文件不是由 delve 构建的,则它不起作用。
restart (alias: r) ---------- 重启进程。
step (alias: s) ------------- 单步执行程序。
step-instruction (alias: si) 单步执行单个 CPU 指令。
stepout (alias: so) --------- 跳出当前功能。
操作断点:
break (alias: b) ------- 设置断点。
breakpoints (alias: bp) 打印活动断点的信息。
clear ------------------ 删除断点。
clearall --------------- 删除多个断点。
condition (alias: cond) 设置断点条件。
on --------------------- 当遇到断点时执行命令。
toggle ----------------- 打开或关闭断点。
trace (alias: t) ------- 设置跟踪点。
watch ------------------ 设置观察点。
查看程序变量和内存:
args ----------------- 打印函数参数。
display -------------- 每次程序停止时打印表达式的值。
examinemem (alias: x) 检查给定地址处的原始内存。
locals --------------- 打印局部变量。
print (alias: p) ----- 打印指定变量。
regs ----------------- 打印 CPU 寄存器的内容。
set ------------------ 更改变量的值。
vars ----------------- 打印包变量。
whatis --------------- 打印表达式的类型。
线程和 goroutine 之间的列表和切换:
goroutine (alias: gr) -- 显示或更改当前 goroutine。
goroutines (alias: grs) 列出程序 goroutine。
thread (alias: tr) ----- 切换到指定线程。
threads ---------------- 打印出每个跟踪线程的信息。
查看调用堆栈和选择帧:
deferred --------- 在延迟调用的上下文中执行命令。
down ------------- 向下移动当前帧。
frame ------------ 设置当前帧,或在不同的帧上执行命令。
stack (alias: bt) 打印堆栈跟踪。
up --------------- 向上移动当前帧。
其他命令:
config --------------------- 更改配置参数。
disassemble (alias: disass) 反汇编器。
dump ----------------------- 从当前进程状态创建核心转储。
edit (alias: ed) ----------- 在 $DELVE_EDITOR 或 $EDITOR 中打开您所在的位置
exit (alias: quit | q) ----- 退出调试器。
funcs ---------------------- 打印功能列表。
help (alias: h) ------------ 打印帮助消息。
libraries ------------------ 列出加载的动态库。
list (alias: ls | l) ------- 显示源代码。
source --------------------- 执行包含 delve 命令列表的文件。
sources -------------------- 打印源文件列表。
types ---------------------- 打印类型列表。
在命令前键入help来获得命令的完整文档,如help goroutine
使用样例:
所调试的进程如果是通过go build打包的,那么需要增加gcflags
参数
go build -gcflags="all=-N -l"
设置断点
b cmp/jogmgr/internal/jobctl.go:184
在命中点上,偏移量+2加断点
b +2
调试已经启动的进程
dlv attach [pid]