我想知道如何单步执行运行时代码(大概是在 Visual Studio Code 中)。我不认为这个问题与 Go 的任何特定版本有关,但就上下文而言,我在 Intel Mac 上使用 1.18.3。
我想要做什么:给定源代码,我想跟踪映射分配如何通过调用链发生。
package main
func main() {
m := make(map[int]int)
m[1] = 100
}
当前的方法:我正在使用 Delve(版本 1.9.0)并在第 5 行
m[1] = 100
语句上设置断点。然后我可以使用step-instruction来浏览汇编级代码,例如
map-example.go:4 0x105a979 8401 test byte ptr [rcx], al
map-example.go:4 0x105a97b 89410c mov dword ptr [rcx+0xc], eax
map-example.go:4 0x105a97e 488d9c24c8000000 lea rbx, ptr [rsp+0xc8]
map-example.go:4 0x105a986 48899c24a8000000 mov qword ptr [rsp+0xa8], rbx
map-example.go:5 0x105a98e 488d05ab580000 lea rax, ptr [rip+0x58ab]
=> map-example.go:5 0x105a995 b901000000 mov ecx, 0x1
map-example.go:5 0x105a99a e86142fbff call $runtime.mapassign_fast64
map-example.go:5 0x105a99f 48898424b0000000 mov qword ptr [rsp+0xb0], rax
map-example.go:5 0x105a9a7 8400 test byte ptr [rax], al
map-example.go:5 0x105a9a9 48c70064000000 mov qword ptr [rax], 0x64
map-example.go:6 0x105a9b0 488bac24f8000000 mov rbp, qword ptr [rsp+0xf8]
我尝试过 step 函数,但我认为它会跳过内置函数并直接跳转到源代码级别的下一行。
问题:除了汇编级别之外,还有其他方法可以调试/跟踪运行时代码吗?我特别想追踪
runtime.mapassign_fast64
或 runtime.mapaccess1
。
感谢您的宝贵时间,感谢您的帮助!
不知道 Visual Studio Code 和运行时断点的“直接”调试,但我可以说我是如何在 Goland IDE 中做类似的事情的。我刚刚将源代码添加为项目,然后 GOROOT -> go SDK -> 项目从项目目录 bin/ 转到二进制文件(可以击败“内部包错误”),然后添加这样的 println 指令:
func makeBucketArray(t *maptype, b uint8, dirtyalloc unsafe.Pointer) (buckets unsafe.Pointer, nextOverflow *bmap) {
println("makeBucketArray")
println(b)
并在 src->runtime->map_test.go 中添加了单元测试。完成此操作后,您可以研究 Go 地图的工作原理。并且不要忘记在测试配置中添加“CGO_ENABLED=0”环境变量以避免错误“致命错误:bits/libc-header-start.h”