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