简体   繁体   English

如何观看 go map 的初始化

[英]How to watch the init of the go map

I use the delve to debug galang code in vscode.我使用 delve 调试 vscode 中的 galang 代码。 I want to use the delve to see the the creation of the golang map,and I create a breakpoint when use the make function to init the map,but it just cannot step into.我想使用 delve 来查看 golang map 的创建,我在使用 make function 初始化 map 时创建了一个断点,但它无法进入。

You can use delve to debug the runtime, however you will need to get familiar with the dlvcommand line interface (without using a GUI).您可以使用 delve 调试运行时,但是您需要熟悉dlv命令行界面(不使用 GUI)。

I will be using the following program as an example:我将使用以下程序作为示例:

package main

func main() {
    abc := make(map[string]int)
    abc["a"] = 1
    abc["b"] = 2
    abc["c"] = 2
    fmt.Println(abc)
}

We can ask delve to build and debug our program with the dlv debug command.我们可以使用dlv debug命令让 delve 构建和调试我们的程序。 This will drop us into the interactive debugger.这将使我们进入交互式调试器。

One of the things that makes maps "fun" to debug is that the compiler can create maps in different ways.使地图调试“有趣”的一件事是编译器可以以不同的方式创建地图。 We first need to know which functions the compiler is using to create a map(can be several depending on map size).我们首先需要知道编译器使用哪些函数来创建映射(根据 map 的大小,可以是多个)。 We will ask delve to disassemble the main func with the disassemble -l main.main command:我们将要求 delve 使用disassemble -l main.main命令反汇编 main 函数:

(dlv) disassemble -l main.main
TEXT main.main(SB) /home/caveman/Downloads/test/main.go
        main.go:7       0x4b6860        64488b0c25f8ffffff              mov rcx, qword ptr fs:[0xfffffff8]
        main.go:7       0x4b6869        488d4424f0                      lea rax, ptr [rsp-0x10]
        main.go:7       0x4b686e        483b4110                        cmp rax, qword ptr [rcx+0x10]
        main.go:7       0x4b6872        0f8668010000                    jbe 0x4b69e0
        main.go:7       0x4b6878        4881ec90000000                  sub rsp, 0x90
        main.go:7       0x4b687f        4889ac2488000000                mov qword ptr [rsp+0x88], rbp
        main.go:7       0x4b6887        488dac2488000000                lea rbp, ptr [rsp+0x88]
        main.go:8       0x4b688f        e84c86f5ff                      call $runtime.makemap_small
        main.go:8       0x4b6894        488b0424                        mov rax, qword ptr [rsp]
        main.go:8       0x4b6898        4889442430                      mov qword ptr [rsp+0x30], rax
        ...

Now this looks complicated, but we just have to look for calls to the runtime.现在这看起来很复杂,但我们只需要查找对运行时的调用。 In this case call $runtime.makemap_small a call to the makemap_small function.在这种情况下, call $runtime.makemap_small调用makemap_small function。

Now that we know this, we need to make a breakpoint in this runtime function.现在我们知道了这一点,我们需要在这个运行时 function 中下一个断点。 We do this using the break mkSmallMap runtime.makemap_small command:我们使用break mkSmallMap runtime.makemap_small命令执行此操作:

(dlv) break mkSmallMap runtime.makemap_small
Breakpoint mkSmallMap set at 0x40eeef for runtime.makemap_small() /usr/local/go/src/runtime/map.go:292

Now we can start our program by executing the c (continue) command:现在我们可以通过执行c (继续)命令来启动我们的程序:

(dlv) c
> [mkSmallMap] runtime.makemap_small() /usr/local/go/src/runtime/map.go:292 (hits goroutine(1):1 total:1) (PC: 0x40eeef)
Warning: debugging optimized function
   287: }
   288:
   289: // makemap_small implements Go map creation for make(map[k]v) and
   290: // make(map[k]v, hint) when hint is known to be at most bucketCnt
   291: // at compile time and the map needs to be allocated on the heap.
=> 292: func makemap_small() *hmap {
   293:         h := new(hmap)
   294:         h.hash0 = fastrand()
   295:         return h
   296: }
   297:

We break in the runtime function itself.我们打破了运行时 function 本身。 The help command will help you get started with all the commands you need for debugging. help命令将帮助您开始使用调试所需的所有命令。 A few basic ones:几个基本的:

  • continue (alias: c) --------- Run until breakpoint or program termination.继续(别名:c) --------- 运行直到断点或程序终止。
  • next (alias: n) ------------- Step over to next source line.下一个(别名:n) ------------- 跳到下一个源代码行。
  • step (alias: s) ------------- Single step through program. step (别名: s) ------------- 单步执行程序。
  • stepout (alias: so) --------- Step out of the current function. stepout(别名:so)--------- 跳出当前的function。
  • list (alias: ls | l) ------- Show source code. list (别名: ls | l) ------- 显示源代码。
  • args ----------------- Print function arguments. args ----------------- 打印 function arguments。
  • locals --------------- Print local variables. locals --------------- 打印局部变量。

If we change the map creation to abc:= make(map[string]int, 100000) you will see in the disassembly that the runtime function has changed to runtime.makemap which is likely of more interest to you.如果我们将 map 创建更改为abc:= make(map[string]int, 100000)您将在反汇编中看到运行时 function 已更改为runtime.makemap ,您可能更感兴趣。

I hope this gets you going, please leave a comment if you need clarification on anything.我希望这能让你继续前进,如果你需要澄清任何事情,请发表评论。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM