Delve 调试器 Delve 调试器 目前 Go 语言支持 GDB、LLDB 和 Delve 几种调试器。其中 GDB 是最早支持的调试工具,LLDB 是 macOS 系统推荐的标准调试工具。但是 GDB 和 LLDB 对 Go 语言的专有特性都缺乏很大支持,而只有 Delve 是专门为 Go 语言设计开发的调试工具。而且 Delve 本身也是采用 Go 语言开发,对 Windows 平台也提供了一样的支持。本节我们基于 Delve 简单解释如何调试 Go 汇编程序。
idea 上的 dlv 调试 一般我们都用idea来开发go,这上面带的断点调试工具就是 dlv。
我这边本地 用的版本有以下几个:
idea-IU-203.7148.57
idea-IU-211.7628.21
GoLand-2021.1.3
里面默认带的 dlv 版本 都是 1.6.1 的
1 2 3 Delve Debugger Version: 1.6.1 Build: 7a3faca71f7e01a97833e11ebf0683543e8159cb
idea 上 断点调试go 的问题 dlv 调试 卡死,分步往下没响应的 问题。
这一段时间发现 有些时候 断点 调试 不能很好的使用了,执行的时候 断点那里
可以停下来,但是 继续按 “步过”, “步入” 等都不好使了。 使得调试非常痛苦。
只能 在下一行 多打几个断点,这样才基线执行 会 停到下一行。
经过尝试 切换 idea 版本 发现 也不行,由于 没有切换 最新的2022版本的也不得而知 是否好使。
然后偶然间 去看了看 这个 dlv 的版本,然后尝试 切换一下 新的版本的dlv,发现好使了!!!!!!!
idea 上 dlv 路径 偶然间发现 dlv 的路径:
在 idea 上是 这个路径
1 ~/.local/share/JetBrains/IntelliJIdea2021.1/go/lib/dlv/linux/dlv
在 goland 上 是 这个路径
1 ~/GoLand-2021.1.3/plugins/go/lib/dlv/linux/dlv
idea 上 切换 dlv 版本 安装个最新的dlv
1 go install github.com/go-delve/delve/cmd/dlv@v1.9.1
这个会安装到 ~/go/bin 目录下面
把这个 新版本的 复制到 idea 目录下面,如下所示,多个dlv 都带上个版本号,然后做个软连接指向其中的一个, 如果要切换不同版本的,可以修改软连接的指向就行。
1 2 3 4 5 6 7 8 9 10 . ├── dlv -> dlv-1.7.0 ├── dlv-1.6.1 ├── dlv-1.7.0 ├── dlv-1.7.1 好使了 ├── dlv-1.7.2 好使了 ├── dlv-1.7.3 好使了 └── dlv-1.9.1 好使了
通过多个版本的尝试 ,发现 到 1.7.1 版本好使了, 1.6.1 和 1.7.0 都有问题。
idea 上 配置 dlv 路径 网上 搜到的其他方法:
1 打开IDEA -> help -> Edit Custom Properties, 输入 dlv.path=D:/go/bin/dlv.exe
不过觉得没我上面的方法好。
找到 v1.7.1 和 v1.7.0 中哪个提交修复了 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 * df1108b2 * *: v1.7.1 (#2662) <Derek Parker >[2021-08-18 00:08 2021-08-18 09:08] (HEAD, tag: v1.7.1) * a4d416d5 * service/dap: add test that verifies output path is relative to wd (#2656) <polinasok >[2021-08-17 11:40 2021-08-17 11:40] * 694b45c8 * service/dap: fix noDebug mode to handle requests while running (#2658) <polinasok >[2021-08-16 08:51 2021-08-16 08:51] * 51375157 * service: fix sameuser check (#2642) <Alessandro Arzilli>[2021-08-10 11:40 2021-08-10 11:40] * c426c5b3 * pkg/proc: configure target to not clear stepping breakpoints (#2635) <Suzy Mueller >[2021-08-09 11:56 2021-08-09 10:56] * 4264bf00 * proc,terminal,service: support stack watchpoints (#2521) <Alessandro Arzilli>[2021-08-09 19:41 2021-08-09 10:41] * f3e76238 * proc: move breakpoint condition evaluation out of backends (#2628) <Alessandro Arzilli>[2021-08-09 19:16 2021-08-09 10:16] * 4e5bddee * cmd/dlv: use simple chan read instead of select-case (#2649) <hitzhangjie >[2021-08-10 01:08 2021-08-09 10:08] * 6b83e6ba * vendor: run go mod vendor (#2647) <hitzhangjie >[2021-08-06 14:26 2021-08-06 08:26] * e175d68e * service/dap: fix race condition in TestContinueOnEntry (#2641) <Alessandro Arzilli>[2021-08-06 07:19 2021-08-05 22:19] * 43d50202 * pkg/terminal: Allow fuzzy searching tab completions (#2633) <Derek Parker >[2021-08-05 10:55 2021-08-05 19:55] * 985eca46 * service/dap: log execution-halted message when setting breakpoints (#2631) <polinasok >[2021-08-05 10:16 2021-08-05 10:16] * 7caa534d * service/debugger: Remove target lock on GetBufferedTracepoints (#2645) <Derek Parker >[2021-08-05 04:53 2021-08-05 13:53] * 2971fd4c * service/dap: fix TestNextParked/TestStepInParked (#2643) <Alessandro Arzilli>[2021-08-04 23:12 2021-08-04 14:12] * 4e242098 * tests: check presence of gcc for cgo tests (#2644) <Alessandro Arzilli>[2021-08-04 23:12 2021-08-04 14:12] * f95340ae * pkg/proc: Fix build errors (#2637) <Derek Parker >[2021-08-04 01:00 2021-08-04 10:00] * 74627673 * teamcity: report go test exit code on windows (#2638) <nd >[2021-08-03 19:42 2021-08-03 10:42] * fdb5189e * dwarf/op,proc: implement more DWARF expression opcodes (#2606) <Alessandro Arzilli>[2021-08-03 18:51 2021-08-03 09:51] * 229fcf15 * cmd: refactor building logic into a helper (#2629) <polinasok >[2021-08-03 09:48 2021-08-03 09:48] * df5812bf * pkg/proc: add tests for next interrupted by bp (#2632) <Suzy Mueller >[2021-08-03 10:47 2021-08-03 09:47] * 10406f96 * *: Initial eBPF tracing support (#2625) <Derek Parker >[2021-07-31 08:16 2021-07-31 17:16] * 89ed5a0b * service/dap: page stack frames (#2597) <Suzy Mueller >[2021-07-29 11:34 2021-07-29 10:34] * b87a1fc5 * service/dap: make next while nexting error more clear (#2622) <Suzy Mueller >[2021-07-29 11:27 2021-07-29 10:27] * a2b83999 * Fix crashes on Go dev.typeparams (soon to be Go main branch) (#2627) <Austin Clements >[2021-07-28 11:18 2021-07-28 08:18] * cb73ef8f * pkg/terminal: Ignore existing breakpoints for continue until (#2624) <Derek Parker >[2021-07-28 04:13 2021-07-28 13:13] * 56731bd8 * Documentation: Improve help output for examinemem (#2623) <Derek Parker >[2021-07-28 04:12 2021-07-28 13:12] * f6681c60 * pkg/proc: Prefer throw instead of fatalthrow (#2616) <Derek Parker >[2021-07-27 23:58 2021-07-27 23:58] * 26e7f67c * cmd/dlv: dlv version --verbose (#2615) <Hyang-Ah Hana Kim >[2021-07-27 12:38 2021-07-27 09:38] * 2ecc0253 * terminal: add prompt when breakpoint is hit during next/step/stepout (#2548) <Alessandro Arzilli>[2021-07-26 17:57 2021-07-26 08:57] * e9b20d5e * proc: use signed comparison when searching image for module data (#2621) <Alessandro Arzilli>[2021-07-26 17:40 2021-07-26 08:40] * 150ef041 * TeamCity: prefer go rc builds over beta (#2619) <nd >[2021-07-24 20:14 2021-07-24 11:14] * aaed14ff * service/dap: fix backend parsing in replay mode (#2618) <polinasok >[2021-07-23 14:04 2021-07-23 14:04] * f1edc45f * service/dap: disable TestFatalThrowBreakpoint for Go 1.17 (#2614) <Suzy Mueller >[2021-07-23 11:12 2021-07-23 10:12] * 39274f60 * proc: make moduleDataToImage more robust (#2613) <Alessandro Arzilli>[2021-07-23 18:21 2021-07-23 09:21] * f74b7a6e * all: update github.com/spf13/cobra to v1.1.3 (#2572) <Hyang-Ah Hana Kim >[2021-07-22 14:05 2021-07-22 11:05] * 89890735 * terminal: improve 'on' command (#2556) <Alessandro Arzilli>[2021-07-22 19:16 2021-07-22 10:16] * b7d8edcd * service/dap: handle unexpected debugger termination (EOF) error (#2574) <polinasok >[2021-07-22 08:52 2021-07-22 08:52] * b41e47a3 * teamcity: use same token everywhere (#2609) <nd >[2021-07-21 17:35 2021-07-21 08:35] * 3941af1d * service/dap: limit the number of goroutines to return from a threads request (#2595) <Suzy Mueller >[2021-07-21 10:26 2021-07-21 08:26] * 658d36cb * proc: allow multiple overlapping internal breakpoints (#2519) <Alessandro Arzilli>[2021-07-21 17:24 2021-07-21 08:24] * c5e533b1 * Treat SIGTERM as a server disconnect signal (#2580) <polinasok >[2021-07-21 07:43 2021-07-21 07:43] * 69615b36 * service/dap: Support for replay and core modes (#2367) <Luis Gabriel Gomez>[2021-07-21 11:38 2021-07-21 07:38] * a14bec4c * Make teamcity ui settings readonly (#2608) <nd >[2021-07-21 16:26 2021-07-21 07:26] * 65f43649 * teamcity: specify working github token in dsl (#2607) <nd >[2021-07-21 16:19 2021-07-21 16:19] * 776b86ff * service/dap: send continued event before step response (#2594) <Suzy Mueller >[2021-07-20 10:51 2021-07-20 08:51] * 38aaf274 * service/dap: fix TestPreSetBreakpoint (#2600) <Alessandro Arzilli>[2021-07-19 17:09 2021-07-19 08:09] * d6556b85 * TeamCity: remove 1.16 testing for linux/arm64, windows/amd64 and mac/* (#2601) <Alessandro Arzilli>[2021-07-19 17:03 2021-07-19 08:03] * 4e78f7f3 * service/dap: add modes comments (TODO from PR/2367) (#2575) <polinasok >[2021-07-18 11:06 2021-07-18 20:06] * af378d39 * service/dap: add backend launch/attach attribute (#2567) <polinasok >[2021-07-18 02:37 2021-07-18 11:37] * 2a22af2e * teamcity: fix settings (#2598) <nd >[2021-07-17 18:58 2021-07-17 09:58] * feb55342 * service/dap: add len as metadata for map (#2584) <Suzy Mueller >[2021-07-16 16:50 2021-07-16 09:50] * 5459034a * cmd/dap: server - always headless, target - always foregrounded (#2589) <polinasok >[2021-07-16 09:49 2021-07-16 09:49] * 584191a7 * *: Release 1.7.0 (#2591) <Derek Parker >[2021-07-16 06:31 2021-07-16 15:31] (tag: v1.7.0) * 9df8f149 * service/dap: variables response must not have null variables array (#2592) <polinasok >[2021-07-15 14:15 2021-07-15 14:15]
git bisect是一个很有用的命令,用来查找哪一次代码提交引入了错误。 它的原理很简单,就是将代码提交的历史,按照两分法不断缩小定位。所谓"两分法",
就是将代码历史一分为二,确定问题出在前半部分,还是后半部分,不断执行这个过程,直到范围缩小到某一次代码提交。
git bisect start命令启动查错,它的格式如下。
1 $ git bisect start [终点] [起点]
1 2 3 4 5 6 $ git bisect start v1.7.1 v1.7.0 或者用 提交 ID $ git bisect start df1108b2 584191a7
开始之后去测试,如果是好的 就执行
用git bisect good命
如果功能不正常 使用git bisect bad命令
接下来,不断重复这个过程,直到成功找到出问题的那一次提交为止。这时,Git 会给出如下的提示。
然后,使用git bisect reset命令,退出查错,回到最近一次的代码提交。
我们这里是 找 哪个提交 修复的,正好 感觉是 反着来标记的
就是把 good 标记 为 bad, 把 bad 的 标记为 good。技巧, 可以使用个 别名
[alias]
bisect-fixed = bisect bad
bisect-unfixed = bisect good
$ git bisect start
$ git bisect-fixed master
$ git bisect-unfixed $some-old-sha1
高版本git 可以使用 git bisect terms 相关的功能
git bisect terms 用法,自定义 bad,good 标识。 1 git bisect --term-new fixed --term-old broken
有时,你并不是在寻找引入 坏 的提交,而是在寻找导致之间发生变化的提交。
类似 一种“旧”状态 和 “新”状态。例如,您可能正在寻找引入特定修复的提交。或
您可能正在寻找第一次提交,其中源代码文件名最终全部转换为您公司的文件名
命名标准。等等 之类的。
在这种情况下,使用术语“good”和“bad”来指代 变化之前的状态 和变化之后的状态 可能会非常混乱。
这个时候,你可以分别用“old”和“new”来代替“good”和“bad”。(但
注意,你不能在 git bisect 过程中 混合“good”和“bad” 与 “old”和“new”。)
在这个更一般的用法中,你用一个“new”提交(新的具有一种特殊的属性的)
和一个“old”提交(旧的也要具有一种特殊属性,这样你才能区分 新, 旧。)
来 提供git bisect 命令。
每次git bisect检出一个提交时,你都会测试该提交是否具有该属性。如果是这样,
将提交标记为“新”;否则,标记为“旧”。当二分完成时,git bisect将报告哪个提交。
下面给出完整 执行 过程
1 2 3 4 可以使用 reset 重置工作区 状态。 $ git bisect reset 之前的 HEAD 位置是 f6681c60 pkg/proc: Prefer throw instead of fatalthrow (#2616) HEAD 目前位于 df1108b2 *: v1.7.1 (#2662)
git bisect start 开始 指定 起始提交,终点提交, 并且自定义 terms
1 2 3 $ git bisect start --term-new fixed --term-old broken v1.7.1 v1.7.0 二分查找中:在此之后,还剩 25 个版本待测试 (大概 5 步) [f6681c60903cc126ba060f01e2eab1341b06b526] pkg/proc: Prefer throw instead of fatalthrow (#2616)
执行编译命令,然后 手动 在idea 进行 断点调试 来 验证 是否有这个问题,如果有问题 就 标记 为 broken。
1 2 3 4 5 6 7 8 9 $ go mod tidy;make build;./dlv version go build "-ldflags=-X main.Build=f6681c60903cc126ba060f01e2eab1341b06b526" github.com/go-delve/delve/cmd/dlv Delve Debugger Version: 1.7.0 Build: f6681c60903cc126ba060f01e2eab1341b06b526 $ git bisect broken 二分查找中:在此之后,还剩 12 个版本待测试 (大概 4 步) [2971fd4c685aeda74b087078f203436c73f94a07] service/dap: fix TestNextParked/TestStepInParked (#2643)
继续 执行编译命令,然后 手动 在idea 进行 断点调试 来 验证 是否有这个问题,如果没问题 就 标记 为 fixed
1 2 3 4 5 6 7 8 9 $ go mod tidy;make build;./dlv version go build -ldflags "-extldflags -static" "-ldflags=-X main.Build=2971fd4c685aeda74b087078f203436c73f94a07" github.com/go-delve/delve/cmd/dlv Delve Debugger Version: 1.7.0 Build: 2971fd4c685aeda74b087078f203436c73f94a07 $ git bisect fixed 二分查找中:在此之后,还剩 6 个版本待测试 (大概 3 步) [10406f96d539d905fbe8e8d102d7a01e61f26f04] *: Initial eBPF tracing support (#2625)
继续 执行编译命令,然后 手动 在idea 进行 断点调试 来 验证 是否有这个问题,如果没问题 就 标记 为 fixed
1 2 3 4 5 6 7 8 $ go mod tidy;make build;./dlv version go build -ldflags "-extldflags -static" "-ldflags=-X main.Build=10406f96d539d905fbe8e8d102d7a01e61f26f04" github.com/go-delve/delve/cmd/dlv Delve Debugger Version: 1.7.0 Build: 10406f96d539d905fbe8e8d102d7a01e61f26f04 $ git bisect fixed 二分查找中:在此之后,还剩 2 个版本待测试 (大概 2 步) [a2b839990e21690e9e60a74c582c4acece6196d8] Fix crashes on Go dev.typeparams (soon to be Go main branch) (#2627)
继续 执行编译命令,然后 手动 在idea 进行 断点调试 来 验证 是否有这个问题,如果没问题 就 标记 为 fixed
1 2 3 4 5 6 7 8 $ go mod tidy;make build;./dlv version go build "-ldflags=-X main.Build=a2b839990e21690e9e60a74c582c4acece6196d8" github.com/go-delve/delve/cmd/dlv Delve Debugger Version: 1.7.0 Build: a2b839990e21690e9e60a74c582c4acece6196d8 $ git bisect fixed 二分查找中:在此之后,还剩 0 个版本待测试 (大概 1 步) [cb73ef8f83d7837486b3f7b9043ce07df96e466c] pkg/terminal: Ignore existing breakpoints for continue until (#2624)
继续 执行编译命令,然后 手动 在idea 进行 断点调试 来 验证 是否有这个问题,如果没问题 就 标记 为 broken
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 $ go mod tidy;make build;./dlv version go build "-ldflags=-X main.Build=cb73ef8f83d7837486b3f7b9043ce07df96e466c" github.com/go-delve/delve/cmd/dlv Delve Debugger Version: 1.7.0 Build: cb73ef8f83d7837486b3f7b9043ce07df96e466c $ git bisect broken a2b839990e21690e9e60a74c582c4acece6196d8 is the first fixed commit commit a2b839990e21690e9e60a74c582c4acece6196d8 Author: Austin Clements <aclements@csail.mit.edu> Date: Wed Jul 28 11:18:20 2021 -0400 Fix crashes on Go dev.typeparams (soon to be Go main branch) (#2627) * proc: Go 1.18 removes the _defer.siz field As of Go 1.17, the _defer.siz field is always 0 because _defer no longer stores defer call arguments at all. golang.org/cl/326062 removes it entirely for Go 1.18. Simply treat it as 0 if the field is missing from the _defer type. * proc: Go 1.18 changes _defer.fn from *funcval to func() golang.org/cl/325918 changed the type of the _defer.fn field from *funcval to func() for Go 1.18. This CL was later reverted because it caused failures in Delve, but we would like to un-revert it. Handle this change by inspecting the type of this field before decoding it. :040000 040000 9de9310d2c1811c12c21cc0de6992e5b800a6216 f4a5b6ab218dedd7af97bac64cc99174ef1a849e M pkg
二分 查找 分析过程 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 * df1108b2 * (HEAD, tag: v1.7.1) * a4d416d5 * * 694b45c8 * * 51375157 * * c426c5b3 * * 4264bf00 * * f3e76238 * * 4e5bddee * * 6b83e6ba * * e175d68e * * 43d50202 * * 985eca46 * * 7caa534d * * 2971fd4c * 第 2 次 验证 标识 为 fixed * 4e242098 * * f95340ae * * 74627673 * * fdb5189e * * 229fcf15 * * df5812bf * * 10406f96 * 第 3 次 验证 标识 为 fixed * 89ed5a0b * * b87a1fc5 * * a2b83999 * 第 4 次 验证 标识 为 fixed 最终找到 这个提交 修复的 * cb73ef8f * 第 5 次 最后一次 验证 标识 为 broken * 56731bd8 * * f6681c60 * 第 1 次 验证的 标识 为 broken, 二分法,这个估计是 最中间那一个提交, 一共 53 行,这个是 第 26行,刚刚好是中间那一个。 这个往下的 提交 都是 broken 的。 * 26e7f67c * * 2ecc0253 * * e9b20d5e * * 150ef041 * * aaed14ff * * f1edc45f * * 39274f60 * * f74b7a6e * * 89890735 * * b7d8edcd * * b41e47a3 * * 3941af1d * * 658d36cb * * c5e533b1 * * 69615b36 * * a14bec4c * * 65f43649 * * 776b86ff * * 38aaf274 * * d6556b85 * * 4e78f7f3 * * af378d39 * * 2a22af2e * * feb55342 * * 5459034a * * 584191a7 * (tag: v1.7.0) * 9df8f149 *
最终得到如下提交修复了这个问题 a2b839990e21690e9e60a74c582c4acece6196d8 is the first fixed commit
commit a2b839990e21690e9e60a74c582c4acece6196d8
Author: Austin Clements <aclements@csail.mit.edu>
Date: Wed Jul 28 11:18:20 2021 -0400
Fix crashes on Go dev.typeparams (soon to be Go main branch) (#2627)
* proc: Go 1.18 removes the _defer.siz field
As of Go 1.17, the _defer.siz field is always 0 because _defer no
longer stores defer call arguments at all. golang.org/cl/326062
removes it entirely for Go 1.18. Simply treat it as 0 if the field is
missing from the _defer type.
* proc: Go 1.18 changes _defer.fn from *funcval to func()
golang.org/cl/325918 changed the type of the _defer.fn field from
*funcval to func() for Go 1.18. This CL was later reverted because it
caused failures in Delve, but we would like to un-revert it. Handle
this change by inspecting the type of this field before decoding it.
:040000 040000 9de9310d2c1811c12c21cc0de6992e5b800a6216 f4a5b6ab218dedd7af97bac64cc99174ef1a849e M pkg
总结 最终发现 其实 和 go的版本也有关系, dlv 1.6.1 在 go 1.17 及其一下版本可以正常使用。
go 1.18 及其以上 版本 需要使用 dlv 1.7.1 以上的版本了