GO delve(dlv)调试工具笔记及实操

GO delve(dlv)调试工具笔记及实操这个文档总结了 我自己在 linux 通过 delve 上调试 go 代码的一些操作 比较常用的 无论是在调试应用 还是自己 trace 源码都挺好用

这个文档总结了,我自己在linux通过delve上调试go代码的一些操作,比较常用的。无论是在调试应用,还是自己trace源码都挺好用。

GO version: 1.16.8

dlv versoin:1.7.2

dlv安装

$ go install github.com/go-delve/delve/cmd/dlv@latest 

go版本小于1.16的用下面方式安装

$ git clone https://github.com/go-delve/delve $ cd delve $ go install github.com/go-delve/delve/cmd/dlv 

dlv指令

仅列出常用或者会用到的

指令 用处 实操
attach 这个命令将使Delve控制一个已经运行的进程,并开始一个新的调试会话。 当退出调试会话时,你可以选择让该进程继续运行或杀死它。 case1
exec 这个命令将使Delve执行二进制文件,并立即附加到它,开始一个新的调试会话。请注意,如果二进制文件在编译时没有关闭优化功能,可能很难正确地调试它。请考虑在Go 1.10或更高版本上用-gcflags=“all=-N -l “编译调试二进制文件,在Go的早期版本上用-gcflags=”-N -l”。 case2
help 帮助 case3
debug 默认情况下,没有参数,Delve将编译当前目录下的 “main “包,并开始调试。或者,你可以指定一个包的名字,Delve将编译该包,并开始一个新的调试会话。 case4
test test命令允许你在单元测试的背景下开始一个新的调试会话。默认情况下,Delve将调试当前目录下的测试。另外,你可以指定一个包的名称,Delve将在该包中调试测试。双破折号--可以用来传递参数给测试程序。 case5
version 查看dlv版本 case6

dlv调试指令

仅记录个人觉得会用到的指令

断点管理
指令 缩写 用法 案例
break b 设置断点 case7
breakpoints bp 查看当前所有断点 case8
clear / 删除断点 case9
clearall / 删除多个断点 case10
toggle / 启用或关闭断点 case11
程序执行中的调试指令
指令 缩写 用法 案例
continue c 继续执行到一个断点或者程序结束吗 case12
next n 执行下一行代码 case13
restart r 重新执行程序 case14
step s 执行代码的下一步 case15
step-instruction si 执行下一行机器码 case16
stepout so 跳出当前执行函数 case17
参数管理
指令 缩写 用法 案例
args / 打印函数input case18
display / 打印加入到display的变量的值,每次执行下一行代码或下一个断点时 case19
locals / 打印局部变量 case20
print p 打印表达式的结果 case21
set / 设置某个变量的值 case22
vars / 查看全局变量 case23
whatis / 查看变量类型 case24
其他
指令 缩写 用法 案例
disassemble disass 查看反编译后的代码,机器码 case25
exit quit / q 退出 case26
funcs / 打印程序用到的所有函数 case27
help h 帮助信息 case28
list ls / l 打印代码 case29

dlv实操案例

测试代码
package main import ( "fmt" "log" "math/rand" "net/http" "time" ) func count(i, j int) int { 
    yz := 5 result := (i + j) * yz return result } func randHandler(w http.ResponseWriter, r *http.Request) { 
    rand.Seed(time.Now().Unix()) var ( i = rand.Intn(20) j = rand.Intn(20) ) result := count(i, j) _, _ = w.Write([]byte(fmt.Sprintf("%d", result))) } func main() { 
    http.HandleFunc("/rand", randHandler) err := http.ListenAndServe(":8080", nil) if err != nil { 
    log.Fatalf("start server fail: %v", err) } } 
case1 attach

在这里插入图片描述

  1. 背景启动http server
  2. dlv attach 176,attach刚才背景执行的程序的pid。同时,给请求的方法打一个断点。
  3. 发送一个请求给这个http server,应该是会阻塞住
  4. c,继续执行,会执行到打断点的地方,这样就可以对http server的方法进行debug
case2 exec

对一个可执行文件进行调试,是针对编译后的。

注意,如果直接go build -v,那有些代码会被优化掉,比如内联函数,在调试的时候会被忽略掉。比如如下代码:

package main import "fmt" func main(){ 
    a := count(1,2) fmt.Println(a) } func count(i,j int) int{ 
    return i+j } 

这个代码在调试的时候,断点打在第6行,然后s是进不去函数的,因为已经被和谐调了,编译器优化之后了。如果不要编译器优化,需要go build -gcflags "-N -l" -v

case3 help

就是单纯的帮助信息

在这里插入图片描述

case4 debug
case5 test

调试单元测试,单元测试会编译整个包,所以test后面跟的是项目根目录的名称

在这里插入图片描述

case6 version

查看版本

在这里插入图片描述

case7 break

设置断点,设置断点的方法一般就是

  • 包名.方法名,如下面的b main.randHandler。如果方法名全局唯一,那就不用写上包名,可以直接对方法打断点,例如runqput。
  • 文件名:行号,如下面的b main.go:24

在这里插入图片描述

case8 breakpoints
case9 clear

删除某个断点,删除断点一般用的就是id来删除

在这里插入图片描述

case10 clearall
case11 toggle

对断点的启禁用,启用是enable,禁用是disabled。禁用状态下的断定,不会执行断点该有的功能。

在这里插入图片描述

case12 continue

continue一般是执行到下一个断点的地方,如果没有设置断点,那就直接执行程序完成,通常用的是缩写c。

以下面例子为例,断点打在randHandler方法上,当请求发过来时,会停在randHandler上,因为打了断点。我们执行命令c可以直接执行到断点的地方,如下图的操作。假设我们在20行再打一个断点,然后再执行c,那会直接跳到20行。

在这里插入图片描述

case13 next

next是执行到一行代码,一行代码即使是函数,也会直接执行过去,不会跳到函数里面。如下图,从17执行到18行

在这里插入图片描述

case14 restart

restart就是重头开始执行,但是断点会保留。所以即使重新执行,有打断点的地方,也会停止在打断点的地方。注意,这个restart只能用在delve自己创建的进程,比如上面的attach,就不能restart。

case15 step

step也是执行一行代码,和next不同的是,如果是函数调用,就会进到函数里面

在这里插入图片描述

case16 step-instruction

step-instruction,主要是针对汇编代码,指的是执行一个机器指令,在没有对代码反编译的时候,作用和step一样。接上上图,disass取得反编译的代码,然后执行si,就可以只执行一行汇编代码。

在这里插入图片描述
在这里插入图片描述

case17 stepout

s进一个函数之后,发现不是想要trace的函数,可以通过stepout,直接跳出函数

在这里插入图片描述

case18 args

打印当前函数的输入参数的值,这个在调试函数的时候很重要

在这里插入图片描述

case19 display

display就是相当于把你想要监控的变量,在每执行一行的时候都打印出来。

case20 locals

打印当前函数的局部变量,这个在调试函数的初始值的时候非常方便。

在这里插入图片描述

case21 print
case22 set

set可以设置某个变量的值,这个在调试边界条件,或者出现bug,想要继续调下去的时候非常有用

在这里插入图片描述

case23 vars

vars是打印全局变量,这个程序里面的,所以也包含一些runtime里面的。如果是自己的全局变量,最好带上名称,或者用正则表达式过滤。

case24 whatis

whatis是打印某个变量的类型

在这里插入图片描述

case25 disassemble

反编译,在case16里面有用到。反编译这个指令一般我是在trace源码的时候才会用到的,想看下源码里面到底是怎么执行的。或者是go底层一些逻辑是汇编写的,才会去用这个反编译。反编译里面踩过的一个坑,可以见:

Go_dlv_autogenerate_代码定位_非晓为骁的博客-CSDN博客

case26 exit

退出,不用说了

case27 funcs

和vars一样,也是整个程序的,查看所有的方法。要想找到自己的方法,最好加上包名,或者通过正则表达式。

case28 help

查看任何一个指令的使用方式,说明。

case29 list

查看代码,因为有时候比如在反编译,或者执行什么表达式了,忘了代码执行到哪里了,可以用一下list。


有其他用到的觉得好用的指令,也可以多多交流呀。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/221834.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午5:11
下一篇 2026年3月17日 下午5:11


相关推荐

  • ES6 的扩展运算符

    ES6 的扩展运算符扩展语法 1 函数 rest 参数 ES6 引入 rest 参数也叫剩余参数 用于获取函数的多余参数 可以替代使用 arguments 对象 出现在函数参数列表的最后 那么它就是 rest 参数 它会把参数列表中剩余的参数收集到一个数组中 rest 参数组成的变量是一个数组 该变量将多余的参数放入数组中函数的 length 属性 不包括 rest 参数 functionrest arg console log arg restFn 1 true name

    2026年3月17日
    1
  • Cursor宣布,学生免费!!!

    Cursor宣布,学生免费!!!

    2026年3月16日
    2
  • webpack基本配置项_webpack配置文件详解

    webpack基本配置项_webpack配置文件详解前言上篇我们已经配置好了本地开发服务器,但是配置的相对比较凌乱,一个文件中有些是开发时用到的配置,有些是生成时用到的配置,有些是开发和生成都要用到的配置,所以我们这里把环境分为3个环境webpac

    2022年8月7日
    12
  • PHP header 的7种用法

    PHP header 的7种用法

    2021年10月26日
    43
  • 离散数学知识点总结

    离散数学知识点总结3 1 高级概念 k core k truss k clique k club p cohesion k edge vertexconnec k shell 同态核 像同态定理 单 甲是乙的一个子群 满 甲的一个商群是乙 非单非满 甲的一个商群是乙的一个子群 双 甲就是乙 2 一阶逻辑基本概念 个体词 常项 变项 约束 自由 假言推理 附加 化简 拒取 假言三段论 析取三段论 构造性二难 破坏性二难 合取引入 2 基本概念 点 边 邻域 前驱 后继 关联边 端点 相邻边 割 桥

    2026年3月19日
    1
  • 关闭对话框,OnClose和OnCancel

    关闭对话框,OnClose和OnCancel

    2021年11月28日
    73

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号