1 回答

TA貢獻(xiàn)1820條經(jīng)驗(yàn) 獲得超9個(gè)贊
您可以使用 delve 調(diào)試運(yùn)行時(shí),但是您需要熟悉dlv
命令行界面(不使用 GUI)。
我將使用以下程序作為示例:
package main
func main() {
abc := make(map[string]int)
abc["a"] = 1
abc["b"] = 2
abc["c"] = 2
fmt.Println(abc)
}
我們可以要求 delve 使用命令構(gòu)建和調(diào)試我們的程序dlv debug。這將使我們進(jìn)入交互式調(diào)試器。
使地圖調(diào)試“有趣”的一件事是編譯器可以以不同的方式創(chuàng)建地圖。我們首先需要知道編譯器使用哪些函數(shù)來創(chuàng)建地圖(根據(jù)地圖大小可以有多個(gè))。我們將要求 delve 使用以下disassemble -l main.main命令反匯編 main func:
(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
...
現(xiàn)在這看起來很復(fù)雜,但我們只需要查找對(duì)運(yùn)行時(shí)的調(diào)用。在這種情況下call $runtime.makemap_small,調(diào)用makemap_small函數(shù)。
現(xiàn)在我們知道了這一點(diǎn),我們需要在這個(gè)運(yùn)行時(shí)函數(shù)中設(shè)置一個(gè)斷點(diǎn)。我們使用以下break mkSmallMap runtime.makemap_small命令執(zhí)行此操作:
(dlv) break mkSmallMap runtime.makemap_small
Breakpoint mkSmallMap set at 0x40eeef for runtime.makemap_small() /usr/local/go/src/runtime/map.go:292
現(xiàn)在我們可以通過執(zhí)行c(繼續(xù))命令來啟動(dòng)我們的程序:
(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:
我們打破了運(yùn)行時(shí)函數(shù)本身。該help命令將幫助您開始使用調(diào)試所需的所有命令。幾個(gè)基本的:
繼續(xù)(別名:c) --------- 運(yùn)行直到斷點(diǎn)或程序終止。
下一個(gè)(別名:n) ------------- 跳到下一個(gè)源代碼行。
step (別名: s) ------------- 單步執(zhí)行程序。
stepout (別名: so) --------- 跳出當(dāng)前函數(shù)。
list (別名: ls | l) ------- 顯示源代碼。
args ----------------- 打印函數(shù)參數(shù)。
locals --------------- 打印局部變量。
如果我們將地圖創(chuàng)建更改為abc := make(map[string]int, 100000)您將在反匯編中看到運(yùn)行時(shí)函數(shù)已更改為runtime.makemap您可能更感興趣的內(nèi)容。
我希望這能讓你繼續(xù)前進(jìn),如果你需要澄清任何事情,請(qǐng)發(fā)表評(píng)論。
- 1 回答
- 0 關(guān)注
- 111 瀏覽
添加回答
舉報(bào)