一、源起
随着微客服系统的功能不断添加、完善,错误也越来越多,更需要进行在线调试。虽然以前也看过delve,但也没有真正用起来,这也导致开发整体进度偏慢。
下载太慢,还是通过码云克隆迅速完成新版本编译。
今天(06.12)对dlv进行了较全面的汉化,辅助翻译软件,虽然未必都很贴切,但比英文看起顺眼许多。
二、一般调试
dlv debug test.go 就这样开始了
b main.main 打个断,需要在运行状态下才行。
b te.go:10 通过文件名加行号的方式打断点
bp 查看下的断点
list 查看当前前后5行语句
clearall 清除所有断点,否则下次r重运行程序时依然存在
c 让程序走到下断的地方停下
n 没啥问题就运行到下一句,接着回车就继续上一个命令,即运行下一句
p msg 显示变量内容,这个应该会经常用在调试中
locals 显示局部变量
args 获取函数的参数
whatis msg 显示表达式类型
s 单步执行程序
so 跳出当前函数,特别是当单步执行时,我们不希望看太多细节函数的调用
p len(msg) 运行一个表达式也是可以的
b counting 给某个函数下断
on x 当运行到断点时,进行某些操作。on 1 print “ok”
set 设置变量值,但只能是数值或指针
r 让程序重新运行
q 退出
三、附身在可执行程序上
还可以attach到一个已在运行中的程序中进行调试,这对于已经上线的程序比较有用。
先找到pid
然后 dlv attach pid
但我遇到两种错误信息:
Could not attach to pid 15539: this could be caused by a kernel security setting, try writing “0” to /proc/sys/kernel/yama/ptrace_scope
could not attach to pid 15558: could not open debug info
原来是我在编译时使用了相关参数:go build -ldflags “-s -w”
-s: 去掉符号信息。
-w: 去掉DWARF调试信息。
四、隔山打牛:远程调试
远程调试也是比较实用的功能,实际就是dlv内部实现了TCP通信而已。
远端(即需要调试程序的电脑上)attach 到一个程序,并且开放一个监听端口供本端接入: dlv attach 7148 –headless –listen=:2345 –api-version=2 –accept-multiclient
本端(即调试机):
dlv connect 127.0.0.1:2345
五、问 题
- 在运行打断之前,我要怎么样显示代码呢?不显示代码,我怎么知道断到哪行呢。
因为下断的行号,似乎并不是源代码的行号。
- 运行中如何及时中断,便于实时查看相关信息
六、其 它
** 关闭编译器优化 **
正常go build/install出的go程序是完全优化过的, 强行使用调试器挂接调试时, 某些local变量/lamda表达式捕获的变量会直接进入寄存器, 无法使用调试器查看。
删掉所有的pkg, 为build或install参数加入关闭编译器优化的参数 -gcflags “-N -l”
例如: go install -gcflags “-N -l” svc\gamesvc