Go 是一個靜態語言,想要了解我們寫出來的程式碼到底深入做了哪些事情,從組合語言來看是個很直接的方法。官方有教我們使用 GDB 來解析,但是因為 GDB 並不了解 Go 本身的一些內建 lib 結構,和 Go 運作的模型,所以使用 Delve 這個特製給 Go 的工作是最適合的。

建議直接閱讀官方文件安裝文件,這邊只帶過一些我覺得好用的指令。

// hello.go
package main

import "fmt"

func main() {
	fmt.Printf("hello, 世界\n")
}
$ dlv debug hello.go 
Type 'help' for list of commands.
(dlv) r
Process restarted with PID 62368
(dlv) disass main.main
Command failed: wrong number of arguments: disassemble [-a <start> <end>] [-l <locspec>]
(dlv) disass -l main.main
TEXT main.main(SB) ~/go/hello/hello.go
	hello.go:5	0x10b6a50	65488b0c2530000000	mov rcx, qword ptr gs:[0x30]
	hello.go:5	0x10b6a59	483b6110		cmp rsp, qword ptr [rcx+0x10]
	hello.go:5	0x10b6a5d	7642			jbe 0x10b6aa1
	hello.go:5	0x10b6a5f	4883ec48		sub rsp, 0x48
	hello.go:5	0x10b6a63	48896c2440		mov qword ptr [rsp+0x40], rbp
	hello.go:5	0x10b6a68	488d6c2440		lea rbp, ptr [rsp+0x40]
	hello.go:6	0x10b6a6d	488d05bd5f0300		lea rax, ptr [rip+0x35fbd]
	hello.go:6	0x10b6a74	48890424		mov qword ptr [rsp], rax
	hello.go:6	0x10b6a78	48c74424080e000000	mov qword ptr [rsp+0x8], 0xe
	hello.go:6	0x10b6a81	48c744241000000000	mov qword ptr [rsp+0x10], 0x0
	hello.go:6	0x10b6a8a	0f57c0			xorps xmm0, xmm0
	hello.go:6	0x10b6a8d	0f11442418		movups xmmword ptr [rsp+0x18], xmm0
	hello.go:6	0x10b6a92	e88989ffff		call $fmt.Printf
	hello.go:7	0x10b6a97	488b6c2440		mov rbp, qword ptr [rsp+0x40]
	hello.go:7	0x10b6a9c	4883c448		add rsp, 0x48
	hello.go:7	0x10b6aa0	c3			ret
	hello.go:5	0x10b6aa1	e8eaf3f9ff		call $runtime.morestack_noctxt
	hello.go:5	0x10b6aa6	eba8			jmp $main.main
(dlv) q
$ cat ./hello.go